[英]Bluebird (or other Promise library) Keep Promise Error Stack Traces
好的,我可能只是想念那些顯而易見的東西,但是我似乎找不到一般的答案,而且到目前為止,我的Google-Fu失敗了。
在Promise的Catch處理程序中,您如何重新拋出錯誤,同時仍然保持Promise堆棧跟蹤原始錯誤?
那也許不是正確的描述,所以這里有一個例子:
https://jsfiddle.net/8sgj8x4L/19/
使用此代碼,跟蹤的堆棧為:
Warning: a promise was rejected with a non-error: [object String]
at RejectWithAnError (https://fiddle.jshell.net/_display/:51:19)
at https://fiddle.jshell.net/_display/:57:14
From previous event:
at StartTheProgram (https://fiddle.jshell.net/_display/:56:6)
at window.onload (https://fiddle.jshell.net/_display/:67:1)
bluebird.js:1444 Unhandled rejection an error occurred
但是,如果添加了catch處理程序,並且從該處理程序中重新拒絕或拋出了錯誤,則堆棧將成為新的Reject方法調用的位置:
https://jsfiddle.net/8sgj8x4L/18/
哪個跟蹤此堆棧跟蹤:
Warning: a promise was rejected with a non-error: [object String]
at https://fiddle.jshell.net/_display/:65:23
From previous event:
at StartTheProgram (https://fiddle.jshell.net/_display/:61:11)
at window.onload (https://fiddle.jshell.net/_display/:70:1)
bluebird.js:1444 Unhandled rejection an error occurred
您可以看到調度了原始錯誤“ RejectWithAnError”的內部方法從第二個堆棧中消失了,因為該錯誤已被捕獲並重新拋出。
作為參考,這是來自JSFiddle的完整代碼(最新的Bluebird被稱為外部依賴項):
window.P.longStackTraces();
function RejectWithAnError() {
var err = {error: true, message: "an error occurred"};
err.prototype = new Error();
return window.P.reject(err);
}
function StartTheProgram() {
return RejectWithAnError()
// Comment out this catch handler completely, and the Promise stack trace will correctly show the "RejectWithAnError" method as the error origin.
.catch(function (status) {
console.log("[WARN] Catch handler was called.");
// Neither of these lines will show "RejectWithAnError" in the Promise chain stack trace.
// throw status;
return window.P.reject(status);
});
}
StartTheProgram()
(附帶說明,這是我的第一個堆棧溢出問題,所以我希望這是此問題的正確格式。)
編輯:更新了示例以拒絕使用從新的Error
實例繼承的對象實例。
JavaScript中的錯誤在創建時會捕獲其跟蹤,因此,每當您重新拋出該錯誤時,它都會自動捕獲堆棧跟蹤。
但是,您不會拋出錯誤。 因此,藍鳥正在向您發出警告(是的)。 如果您堅持拋出非錯誤而不是正確地將錯誤歸類,則需要通過手動捕獲對象來手動誘使對象具有正確的堆棧跟蹤。 通過在構造函數中創建一個new Error
並將.stack
設置為其堆棧(可能必須進行一些解析),或者通過調用特定方法:
function RejectWithAnError() {
var err = {error: true, message: "an error occurred"};
// err.__proto__ = new Error(); -- this is how you'd do it with prototypes btw
// explicitly capture the stack trace of the object
if(Error.captureStackTrace) Error.captureStackTrace(err);
}
在這里擺弄。 請注意, .prototype
是函數使用的屬性, 用於指示通過將函數作為構造函數調用而創建的對象的原型 。 為了直接設置對象的原型,可以調用__proto__
盡管這__proto__
一個特別好的主意。 這是__proto__
而不是Error.captureStackTrace的示例 。
Promise.config({
warnings: false
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.