Javascript 如何在 Promise 中捕获未捕获的异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28001722/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to catch uncaught exception in Promise
提问by John
Is there any way to globally catch all exceptions including Promise exceptions. Example:
有没有办法全局捕获所有异常,包括 Promise 异常。例子:
window.onerror = function myErrorHandler(errorMsg, url, lineNumber) {
alert("Error occured: " + errorMsg);//or any message
return false;
}
var myClass = function(){
}
var pr = new Promise(function(resolve, react){
var myInstance = new myClass();
myInstance.undefinedFunction(); // this will throw Exception
resolve(myInstance);
});
pr.then(function(result){
console.log(result);
});
// i know right will be this:
// pr.then(function(result){
// console.log(result);
// }).catch(function(e){
// console.log(e);
// });
This script will silently die without error. Nothing in firebug.
此脚本将无声无息地死亡。萤火虫中什么都没有。
My question is if I do a mistake and forgot to catch it is there any way to catch it globally?
我的问题是,如果我犯了一个错误而忘记抓住它,有没有办法在全球范围内抓住它?
回答by Benjamin Gruenbaum
Update, native promises now do the following in most browsers:
更新,本机承诺现在在大多数浏览器中执行以下操作:
window.addEventListener("unhandledrejection", function(promiseRejectionEvent) {
// handle error here, for example log
});
We were just discussing this the other day.
我们前几天刚讨论过这个。
Here is how you'd do this with bluebird:
以下是使用 bluebird 执行此操作的方法:
window.onpossiblyunhandledexception = function(){
window.onerror.apply(this, arguments); // call
}
window.onerror = function(err){
console.log(err); // logs all errors
}
With Bluebird it's also possible to use Promise.onPossiblyUnhandledRejection. The calls for doneare not needed as the library will detect unhandled rejection itself unlike Q (UPDATE 2016 - I now wrote code for Q and it does this).
使用 Bluebird 也可以使用Promise.onPossiblyUnhandledRejection. done不需要调用,因为库会检测到与 Q 不同的未经处理的拒绝本身(更新 2016 - 我现在为 Q 编写了代码,它会这样做)。
As for native promises - they willeventually report to either window.onerror or a new handler but the specification process is not yet done - you can follow it here.
至于本机承诺——它们最终将报告给 window.onerror 或一个新的处理程序,但规范过程尚未完成——你可以在这里遵循它。
回答by JLRishe
Most promise implementations don't currently provide the type of functionality you are referring to, but a number of 3rd-party promise libraries (including Qand bluebird) provide a done()method that will catch and rethrow any uncaught errors, thus outputting them to the console.
大多数 Promise 实现目前不提供您所指的功能类型,但许多 3rd 方 Promise 库(包括Q和bluebird)提供了一种done()方法来捕获并重新抛出任何未捕获的错误,从而将它们输出到控制台.
(Edit:see Benjamin Gruenbaum's answer about Bluebird's features for handling uncaught exceptions)
(编辑:参见 Benjamin Gruenbaum 关于 Bluebird 处理未捕获异常的功能的回答)
So if you have that, you'd just need to follow the rule of thumb that any promise you use should either be returned or terminated with .done():
因此,如果你有这个,你只需要遵循经验法则,你使用的任何承诺都应该返回或终止.done():
pr.then(function(result){
console.log(result);
})
.done();
To quote from the Q API reference:
引用 Q API 参考:
The Golden Rule of
donevs.thenusage is: eitherreturnyour promise to someone else, or if the chain ends with you, calldoneto terminate it. Terminating withcatchis not sufficient because thecatchhandler may itself throw an error.
done与then使用的黄金法则 是:要么return你对别人的承诺,要么如果链条以你结束,调用done终止它。终止catch是不够的,因为catch处理程序本身可能会抛出错误。
I realize that this still requires a bit of extra work and you can still forget to do this, but it is an improvement over having to .catch()and explicitly handle every error, especially for the reason pointed out above.
我意识到这仍然需要一些额外的工作,您仍然可以忘记这样做,但.catch()与必须明确处理每个错误相比,这是一种改进,尤其是由于上面指出的原因。
回答by JussiR
In Node.js, you can use:
在 Node.js 中,您可以使用:
process.on('unhandledRejection', (reason, promise) => {
console.error(`Uncaught error in`, promise);
});
回答by John Slegers
If you're writing code that can be executed both in a browser & in a Node.js environment, you could wrap your code in a self-executing function like this :
如果您正在编写可以在浏览器和 Node.js 环境中执行的代码,您可以将代码包装在一个自执行函数中,如下所示:
var isNode = (typeof process !== 'undefined' && typeof process.on !== 'undefined');
(function(on, unhandledRejection) {
// PUT ANY CODE HERE
on(unhandledRejection, function(error, promise) {
console.error(`Uncaught error in`, promise);
});
// PUT ANY CODE HERE
})(
isNode ? process.on.bind(process) : window.addEventListener.bind(window),
isNode ? "unhandledRejection" : "unhandledrejection"
);
What would happen if you use this code :
如果您使用此代码会发生什么:
If you'd run it in a Node.js environment, your handler would be attached to the process object and be executed when you have an uncaught exception in a promise.
If you'd run it in a browser environment, your handler would be attached to the window object and be executed when you have an uncaught exception in a promise and your browser supports the
unhandledrejectionevent.If you'd run it in a browser environment without support for the
unhandledrejection, you will not be able to catch your uncaught exception and yourunhandledrejectionevent handler will never be triggered, but you would not get any errors if there's no uncaught exceptions.
如果您在 Node.js 环境中运行它,您的处理程序将附加到 process 对象并在您在 Promise 中有未捕获的异常时执行。
如果您在浏览器环境中运行它,您的处理程序将附加到 window 对象并在您的承诺中有未捕获的异常并且您的浏览器支持该
unhandledrejection事件时执行。如果您在不支持 的浏览器环境中运行它
unhandledrejection,您将无法捕获未捕获的异常,并且unhandledrejection永远不会触发您的事件处理程序,但如果没有未捕获的异常,您将不会收到任何错误。
回答by redyyu
If you are using native Promise, it's pretty simple.
You only need to .catchthis reject some where.
如果您使用本机 Promise,则非常简单。
您只需要在.catch此拒绝某些地方。
ajax(request).catch(function(rejected){
console.log(rejected);
});
If I don't catch it somewhere, the uncaught in promise will keep showing. But If I catch it somewhere...
如果我没有在某个地方抓住它,未抓住的承诺将继续出现。但是如果我在某个地方抓住它......

