NodeJS / Express 處理 Uncaught Exception 或是非同步的裡的 Unhandled Rejection
防禦性程式設計 (Defensive programming) 的核心思想就是要在編程設計裡,要考慮到出現不可預計的程式錯誤,從而去防止程式影響日常運作。在 NodeJS 裡,同步 (sync) 的程式有機會出現 Uncaught Exception,而非同步的程式 (包括 Promise 和 Async / Await) 也有機會出現 Unhandled rejections。
- 處理同步出現的 Uncaught Exception
出現 Uncaught Exception 的主要原因在於代碼內出現錯誤,但無法認出是什麼原因的錯誤。舉個例子,在某一個 function 中出現沒有定義的 variable,而代碼裡沒有增加類似的 catching。這樣的話,程式就會報錯。
當 Node 發覺有 uncaught exception 發生,那它在進程 (process) 中就會捕獲到 uncaughtException
,所以我們在那個時候加入錯誤處理就可以了。
// in the last section of app.jsprocess.on('uncaughtException', err ⇒ {
console.log('Uncaughted Exception happens!')
// 記錄錯誤下來,等到所有其他服務處理完成,然後停掉當前進程。
console.log(err);
server.close(() => {
process.exit(1)
});
});
2. 處理非同步出現的 Unhandled Rejection
同樣地,非同步的程式也有可能出現同一情況,這樣就會在進程出現 unhandledRejection
,例如遠端的資料庫連接失敗。我們也可以用同一思路處理:
// in the last section of app.jsprocess.on('unhandledRejection', err ⇒ {
console.log('Uncaughted Exception happens!')
// 記錄錯誤下來,等到所有其他服務處理完成,然後停掉當前進程。
console.log(err);
server.close(() => {
process.exit(1)
});
});
最後,我們可以將它重構,讓它看起來簡單一點:
// in app.js
...
const handleUncaughtExceptionOrRejection = err ⇒ {
console.log('Uncaughted Exception or Unhandled Rejection happens!')
// 記錄錯誤下來,等到所有其他服務處理完成,然後停掉當前進程。
console.log(err);
server.close(() => {
process.exit(1)
});
}
...
process.on('unhandledRejection', handleUncaughtExceptionOrRejection);
process.on('uncaughtException', handleUncaughtExceptionOrRejection);