如何在Promise中捕获未捕获的异常

Joh*_*ohn 68 javascript exception promise

有没有办法全局捕获所有异常,包括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);
    // });
Run Code Online (Sandbox Code Playgroud)

这个脚本会默默地死掉而不会出错.萤火虫没什么.

我的问题是,如果我犯了一个错误,忘了抓住它有没有办法在全球范围内捕捉到它?

Ben*_*aum 26

更新,本机承诺现在在大多数浏览器中执行以下操作:

window.addEventListener("unhandledrejection", function(promiseRejectionEvent) { 
    // handle error here, for example log   
});
Run Code Online (Sandbox Code Playgroud)

我们前几天正在讨论这个问题.

以下是蓝鸟如何做到这一点:

window.onpossiblyunhandledexception = function(){
    window.onerror.apply(this, arguments); // call
}

window.onerror = function(err){
    console.log(err); // logs all errors
}
Run Code Online (Sandbox Code Playgroud)

使用Bluebird它也可以使用Promise.onPossiblyUnhandledRejection.done不需要调用,因为库不会检测未处理的拒绝,而不像Q(2016年更新 - 我现在为Q编写代码并且它执行此操作).

至于本地的承诺-他们最终要么window.onerror或新的处理程序,但是这些规范进程报告尚未完成-你可以在这里遵循它.

  • “大多数浏览器都是 Chrome” 好吧,我想“大多数会话中使用的浏览器”是“大多数浏览器”的一种定义......不是我会选择的一种。 (2认同)

JLR*_*she 15

大多数承诺实现目前不提供您所指的功能类型,但是许多第三方承诺库(包括Qbluebird)提供了一种done()方法,可以捕获并重新抛出任何未捕获的错误,从而将它们输出到控制台.

(编辑:请参阅Benjamin Gruenbaum关于Bluebird处理未捕获异常的功能的答案)

因此,如果你有这个,你只需遵循经验法则,你所使用的任何承诺都应该退回或终止.done():

pr.then(function(result){
    console.log(result);
})
.done();
Run Code Online (Sandbox Code Playgroud)

引用Q API参考:

donethen 使用相关的黄金法则 是: return 您对其他人的承诺,或者如果链条与您结束,请致电 done 终止它.使用终止 catch 是不够的,因为catch处理程序本身可能会抛出错误.

我意识到这仍然需要一些额外的工作,你仍然可以忘记这样做,但它是一个改进,必须.catch()和明确处理每个错误,特别是出于上面提到的原因.

  • 实际上完成与简单地做`.catch(thrower)`没什么不同(或者用快捷方式做同样的事情,例如添加`Promise.prototype.done = ...`.所以对于这个目的来说这是毫无意义的,特别是在bluebird中通常会报告未捕获的错误. (2认同)

Jus*_*siR 5

在 Node.js 中,您可以使用:

process.on('unhandledRejection', (reason, promise) => {
  console.error(`Uncaught error in`, promise);
});
Run Code Online (Sandbox Code Playgroud)