gpt4 book ai didi

Javascript 异常隐藏在 Promises 中。我怎样才能在没有捕获的情况下显示它们?

转载 作者:行者123 更新时间:2023-11-30 07:07:28 25 4
gpt4 key购买 nike

编辑:

正如优秀(已接受)答案所指出的那样, promise 不会隐藏异常。我想详细说明 promise 中的异常是如何不可见的:

我正在从事一个使用专有库进行 ajax 调用的项目。现在,如果 ajax 调用的回调中出现问题,则会抛出异常。然后,此异常将触发 reject() 被调用,然后被静默丢弃。事实上,异常并没有被隐藏,而是在一个空的错误回调中主动处理进一步的代码。这最终导致了甚至很难识别出错误发生的情况。


这里是原始问题:

我知道我可以在我所有的 promise 中添加一个 catch-block 并控制台记录那里的错误。在我的用例中,我需要在调用堆栈的更高级别捕获异常。

http://jamesknelson.com/are-es6-promises-swallowing-your-errors/

在关于 SO 的另一个问题中,接受的答案还提出了 catch-blocks:

Catching errors generated in Promises within Promises in JavaScript

最佳答案

Javascript silently swallows Exceptions that are thrown within a Promise.

不,它没有。在 promise 执行器(你传递给 new Promise 的函数)或 then/catch 处理程序中抛出的异常被用作拒绝的值的 promise 。如果您有未处理的拒绝,任何体面的实现也会记录控制台错误。例如,在最新版本的 Chrome 或 Firefox 中试试这个:

new Promise(() => { throw new Error("Unhandled"); })

在控制台中你会发现:

Uncaught (in promise) Error: Unhandled    at Promise (js:13)    at new Promise ()    at js:13

Soon, NodeJS will start terminating the process on unhandled rejections just like unhandled exceptions. Because rejections are exceptions.

I do not want to add a catch-block to all my promises.

You don't have to. The rule of promises is you either return the promise or handle rejections from it; almost never both. (You'd do both only rarely, such as when you're "wrapping" the error that occurred to make it more high-level.) So you only need a catch on promises that you don't propagate to the caller. Best practice is to propagate to the highest level you can and then handle them there. Most of the time you don't write a catch because you're propagating the promise.

Can I monkey-patch (or else) the native Promises in such a way that they stop hiding my exceptions?

Well, again, they don't. You can replace Promise and Promise.prototype.then so they report exceptions to the console, but you'll end up reporting things that are handled by subsequent handlers and shouldn't be reported. For example:

// NOT RECOMMENDED
const RealPromise = Promise;
Promise = class Promise extends RealPromise {
constructor(executor) {
super((resolve, reject) => {
try {
executor(resolve, reject);
} catch (e) {
console.error(e);
reject(e);
}
});
}

then(onResolved, onRejected) {
return super.then(val => {
try {
return onResolved(val);
} catch (e) {
console.error(e);
throw e;
}
}, onRejected);
}
};

new Promise(() => {
throw new Error("Handled");
}).catch(e => {
console.log("But I handled it!");
});

...但这不是一个好主意,如您所见。

如果您遵循传播或处理规则,您应该可以使用内置 promise 。


可能还值得注意 async/await 语法,这是 ES2017 的新语法:当使用 async/await,promise 拒绝值用作异常,关闭圆圈:

function foo() {
return new Promise((resolve, reject) => {
setTimeout(reject, 500, "Failed");
});
}
(async () => {
try {
await foo();
} catch (e) {
console.log("Got error: ", e);
}
})();

关于Javascript 异常隐藏在 Promises 中。我怎样才能在没有捕获的情况下显示它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46512031/

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