Node處理未捕獲的異常
如何有效處理Node程序的崩潰?首先,你需要明白當一個未捕獲異常拋出時,Node會終止進程的執行。重要的是理解為什麼會存在這種行為,以及如何處理未捕獲的異常,來幫助程序變得穩定。有時候,程序會拋出未處理的異常,而Node默認會終止程序的執行。關於這種處理方式有一個很好的理由,我們過後再提。先來看一下如何修改這一默認的行為。在process對象上可以設置未捕獲異常的處理函數,當異常發生時,Node會執行對應的函數,而不終止程序的運行。
process.on("uncaughtException", function (err) {
console.error(err);
});
是的!這樣子你的Node應用就不會崩潰了!儘管進程再也不會導致程序崩潰,但是如果你選擇繼續運行,該應用可能會泄露內存資源,並且可能變得極其不穩定,這樣可能得不償失。這一切會是怎麼發生的?我們看一下一個需要長時間運行的例子,一個web伺服器。當有未捕獲異常拋出時,我們不允許Node終止程序,而僅僅只是列印錯誤信息。你覺得當一個用戶請求時,程序有一個未捕獲的異常時會有什麼情況發生?
當response未定義時拋出一個引用異常。當一個請求進來時,一個拋出的異常被uncaughtException處理函數所捕獲。這個請求會怎麼樣?這會導致內存泄漏,請求會一直保持著,直至用戶端請求超時(我們也沒有辦法去提供一個返回信息)。在圖中,你可以看到泄漏發生的情況。如果沒有異常,那麼一切都是正常的。但如果異常發生了,那麼便會出現內存泄漏。
雖然這個例子被簡化以便更加容易理解,但是未捕獲的異常是一個現實的問題。大多數時候,它可能是打開的sockets或者文件無法正確地關閉。未捕獲的異常通常在代碼中埋得很深,這會讓確定資源泄露的問題變得異常困難。所在的背景情況也會收到影響,因為沒捕獲的異常會跳出當前的上下文,而讓你身處於一個完全不同的上下文(uncaughtException處理方法),讓你丟失了錯誤相關的對象引用。在我們的例子中,我們沒有辦法訪問到res對象來返回一個請求給客戶端。
那麼uncaughtException的好處是什麼?它讓你的應用可以適時列印日誌以及重啟。把uncaughtException處理方法作為對你即將崩潰的應用說再見的最後機會是很明智的做法。列印錯誤信息,發送一個郵件或者用其它方式通知相關人員,然後優雅地把應用關閉。
uncaughtException的處理函數是最後一道防線。理想情況下,異常應該更加接近發生時來進行處理,以防止泄漏和不穩定來源。對於這一點,你可以使用domain。
雖然uncaughtException處理是基於你整個應用的代碼基礎來捕獲錯誤的,你可以使用域來控制監控部分代碼,把異常的處理放置在更加接近源碼的位置。。讓我們把先前的例子使用域來實現。
創建一個新的域。
在域中執行代碼。
在域中處理異常情況。
給用戶提供錯誤反饋。
使用域允許我們的代碼在一個沙盒中運行,並且可以使用res對象來給用戶反饋,這是上一個例子無法實現的點。儘管我們可以返回錯誤信息,並且關閉連接,但是最好的實踐還是關閉進程。


※一個測試web應用程序的Mocha測試
※簡單的Mocha測試項目的package.json配置文件
※一個關於test測試腳本的pakcage.json配置文件
TAG:行家匯 |
※Python 異常處理
※Servlet 異常處理
※處理異常—Python 基礎
※一文讀懂Python中的異常處理
※Android非同步處理
※批處理ETL已死,Kafka才是數據處理的未來?
※Jdk 動態代理異常處理分析,UndeclaredThrowableException
※Wireshark捕獲過濾器在處理網上問題時的應用
※gate.io關於ZRX市場交易異常處理公告
※常用cookie處理方法工具類
※MySQL Mysqldump 常見問題和處理
※Facebook被曝正在研發處理器
※Android Wear要死了?高通智能手錶處理器已兩年未更迭
※Pytorch 中如何處理 RNN 輸入變長序列 padding
※C 異常處理
※Perl 錯誤處理
※Curr Microbiol:不同處理方式的植體表面菌膜的形成
※Servlet Cookie 處理
※【ASP.NET Core】處理異常
※iPad找不到Apple Pencil了怎麼處理?