簡體   English   中英

藍鳥(或其他Promise庫)保留Promise錯誤堆棧跟蹤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM