今天在使用node運行js文件時,返回了下面的錯誤和警告,警告部分主要是由於使用了promise,可是沒有使用catch來捕捉錯誤.
更詳細的解釋在下面,這是nodejs文檔的process模塊的一部分
用戶deMBP:loveToken 用戶$ node test.js
{ Error: connect ECONNREFUSED 10.240.100.88:8081
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1159:14)
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED',
syscall: 'connect',
address: '10.240.100.88',
port: 8081 }
(node:3718) UnhandledPromiseRejectionWarning: Error: connect ECONNREFUSED 10.240.100.88:8081
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1159:14)
(node:3718) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:3718) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
'rejectionHandled' 事件——異步
若是有 Promise 被 rejected,而且此 Promise在 Node.js 事件循環的下次輪詢及以後期間,被綁定了一個錯誤處理器(即便用了catch的話,就會觸發這個事件)(例如使用 promise.catch()),會觸發 'rejectionHandled' 事件。
此事件監聽器的回調函數使用 rejected 的 Promise 引用,做爲惟一入參。
Promise 對象應該已經在 'unhandledRejection' 事件觸發時被處理,可是在被處理過程當中得到了一個 rejection 處理器。
對於 Promise 鏈,沒有概念代表在 Promise 鏈的哪一個地方,全部的 rejection 老是會被處理。 因爲原本就是異步的,一個 Promise rejection 能夠在未來的某個時間點被處理-可能要遠遠晚於 'unhandledRejection' 事件被觸發及處理的時間。
另外一種表述的方式就是,與使用同步代碼時會出現不斷增加的未處理異常列表不一樣,使用 Promise 時,未處理異常列表可能會出現增加而後收縮的狀況。
在同步代碼狀況下,當未處理異常列表增加時,會觸發 'uncaughtException' 事件。
在異步代碼狀況下,當未處理異常列表增加時,會觸發 'unhandledRejection' 事件,當未處理列表收縮(就是被解決了)時,會觸發 'rejectionHandled' 事件。
例如:
const unhandledRejections = new Map();
process.on('unhandledRejection', (reason, p) => {//未處理
unhandledRejections.set(p, reason);
});
process.on('rejectionHandled', (p) => {//已處理
unhandledRejections.delete(p);
});
在上述例子中,unhandledRejections 會隨着時間增長和縮減,代表 rejection 開始是未被處理狀態,而後變成已處理狀態。 能夠定時(對於需長期運行的應用,這個多是最好的方式)或當進程結束時(對腳本的應用多是最方便的),在錯誤日誌中記錄這些錯誤信息。
'uncaughtException' 事件——同步
若是 Javascript 未捕獲的異常,沿着代碼調用路徑反向傳遞迴事件循環,會觸發 'uncaughtException' 事件。 Node.js 默認狀況下會將這些異常堆棧打印到 stderr 而後進程退出。 爲 'uncaughtException' 事件增長監聽器會覆蓋上述默認行爲。
'uncaughtException' 事件監聽器的回調函數,使用 Error 對象做爲惟一參數值。
例如:
process.on('uncaughtException', (err) => {
fs.writeSync(1, `捕獲到異常:${err}\n`);
});
setTimeout(() => {
console.log('這裏仍然會運行。');
}, 500);
// 故意調用一個不存在的函數,應用會拋出未捕獲的異常。
nonexistentFunc();
console.log('這裏不會運行。');
注意:正確地使用 uncaughtException
須要注意,若是打算使用 'uncaughtException' 事件做爲異常處理的最後補救機制,這是很是粗糙的設計方式。 此事件不該該看成 On Error Resume Next(出了錯誤就恢復讓它繼續)的等價機制。 未處理異常自己就意味着應用已經處於了未定義的狀態。若是基於這種狀態,嘗試恢復應用正常進行,可能會形成未知或不可預測的問題。
此事件的監聽器回調函數中拋出的異常,不會被捕獲。爲了不出現無限循環的狀況,進程會以非零的狀態碼結束,並打印堆棧信息。
若是在出現未捕獲異常時,嘗試去恢復應用,可能出現的結果與電腦升級時拔掉電源線出現的結果相似 -- 10次中有9次不會出現問題,可是第10次可能系統會出現錯誤。
正確使用 'uncaughtException' 事件的方式,是用它在進程結束前執行一些已分配資源(好比文件描述符,句柄等等)的同步清理操做。 觸發 'uncaughtException' 事件後,用它來嘗試恢復應用正常運行的操做是不安全的。
想讓一個已經崩潰的應用正常運行,更可靠的方式應該是啓動另一個進程來監測/探測應用是否出錯, 不管 uncaughtException 事件是否被觸發,若是監測到應用出錯,則恢復或重啓應用。
'unhandledRejection' 事件——異步
若是在事件循環的一次輪詢中,一個 Promise 被 rejected,而且此 Promise 沒有綁定錯誤處理器(就是沒有對它進行處理的操做),’unhandledRejection 事件會被觸發。 當使用 Promise 進行編程時,異常會以 "rejected promises" 的形式封裝。Rejection 能夠被 promise.catch() 捕獲並處理,而且在 Promise 鏈中傳播。'unhandledRejection 事件在探測和跟蹤 promise 被 rejected,而且 rejection 未被處理的場景中是頗有用的。
此事件監聽器的回調函數被傳遞以下參數:
• reason <Error> | <any> 此對象包含了 promise 被 rejected 的相關信息(一般是一個 Error 對象)。
• p 被 rejected 的 promise 對象。
例如:
process.on('unhandledRejection', (reason, p) => {
console.log('未處理的 rejection:', p, '緣由:', reason);
// 記錄日誌、拋出錯誤、或其餘邏輯。
});
somePromise.then((res) => {
return reportToUser(JSON.pasre(res)); // 故意輸錯 `pasre`。
}); // 沒有 `.catch` 或 `.then`。
以下代碼也會觸發'unhandledRejection'事件
function SomeResource() {
// 將 loaded 的狀態設置爲一個 rejected promise。
this.loaded = Promise.reject(new Error('錯誤信息'));
}
const resource = new SomeResource();
// resource.loaded 上沒有 .catch 或 .then。
在例子中,能夠像在其餘 'unhandledRejection' 事件的典型場景中同樣,跟蹤開發者錯誤致使的 rejection。 爲了解決這樣的錯誤,resource.loaded 中能夠加一個不作任何操做的 .catch(() => { }) 處理器, 這樣能夠阻止 'unhandledRejection' 事件的觸發。或者也可使用 'rejectionHandled' 事件來解決。
node