gpt4 book ai didi

javascript - Bluebird(或其他 Promise 库)保留 Promise 错误堆栈跟踪

转载 作者:行者123 更新时间:2023-11-30 16:17:55 24 4
gpt4 key购买 nike

好吧,我可能只是错过了显而易见的东西,但我似乎无法找到这个问题的一般答案,而且我的 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()

(附带说明,这是我的第一个 Stack Overflow 问题,所以我希望这是这个问题的正确格式。)

编辑:更新示例以拒绝使用从新的 Error 实例继承的对象实例。

最佳答案

JavaScript 中的错误会在创建时捕获它们的踪迹,因此无论何时您重新抛出错误,它都会自动捕获堆栈踪迹。

但是你并没有抛出错误。出于这个原因,bluebird 给你一个警告(是的)。如果您坚持抛出非错误而不是正确地子类化错误 - 您将需要通过手动捕获对象来手动欺骗该对象以获得正确的堆栈跟踪。通过在构造函数中创建一个 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);
}

fiddle here .请注意,.prototype 是一个属性由函数使用 来指示通过将函数作为构造函数调用而创建的对象的原型(prototype)。为了直接设置一个对象的原型(prototype),你会调用 __proto__ 尽管这不是一个特别好的主意。这是 __proto__ instead of Error.captureStackTrace 的示例.

关于javascript - Bluebird(或其他 Promise 库)保留 Promise 错误堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35207432/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com