捕获所有未处理的 javascript Promise拒绝

IT技术 javascript es6-promise
2021-02-08 10:40:17

我想捕获在 javascript Promise 中发生的所有未处理的异常/拒绝。有没有一个很好的方法来捕捉它们而不.catch(..)在 Promise 链的每一端添加一个(如果忘记添加这个,错误会悄悄消失)。

Google Chrome 中的开发者控制台可以记录它们,我也喜欢在生产环境中记录它们。

对于普通的 javascript 异常,我使用该window.onerror函数,但来自 Promise 的错误调用此函数。

例子:

window.onerror = function (e) {
    alert("unhandled error: " + e);
};

var p = new Promise(function (resolve, reject) {
    var nullObject = null;
    // Raise a TypeError: Cannot read property 'forceNullError' of null
    var x = nullObject.forceNullError(); 
    resolve();
});

p.then(function () { alert('success'); });

JSFiddle:https ://jsfiddle.net/f7zwej6L/

*) 我注意到 WinJS 有.done(..)我想要方法,但 Native Promises 没有。

4个回答

整个世界都在等待unhandledrejectionrejectionhandled事件。截至 2016 年 3 月,Chrome 现在是第一个支持它的。

例子:

window.addEventListener('unhandledrejection', function(event) {
    console.error('Unhandled rejection (promise: ', event.promise, ', reason: ', event.reason, ').');
});

规范:HTML 生活标准

Mozilla 开发者: onrejectionhandled , onunhandledrejection

铬的问题:495801393913

编辑它以将事件的名称更正为“unhandledrejection”,并提到 Chrome 现在支持它(哇!)。“window.onunhandledrejection”是属性版本。
2021-03-15 10:40:17
caniuse.com/#feat=unhandledrejection表示支持 Chrome 49+、Chrome for Android 70+、iOS Safari 11.3+、UC Browser for Android 11.8+、Safari 11+、Opera 36+、Samsung Internet 5+、Android Browser 67+ .
2021-03-17 10:40:17
似乎它已经在 Chromium 的后备箱中,而且 Firefox 也确实想实现它。我认为它很快就会上市。
2021-03-23 10:40:17
奇怪的。对我来说,它只在启用“捕获异常时暂停”时调用这些函数。
2021-03-26 10:40:17
对于使用 Bluebird 的任何人,仅供参考,该unhandledrejection事件已触发,Promise和原因嵌套在detail事件下方(例如,event.detail.promise而不是event.promise)。bluebirdjs.com/docs/api/...
2021-03-29 10:40:17

请注意,在 Node 中,该事件被称为unhandledRejection

process.on('unhandledRejection', function(err, promise) {
    console.error('Unhandled rejection (promise: ', promise, ', reason: ', err, ').');
});

在版本 12+ 上,节点将在这些拒绝时终止。

注意节点,它unhandledRejection不是unhandledrejection
2021-03-15 10:40:17
@Freewind 很抱歉您发现这令人困惑-我们一直在使用 dom 事件命名与节点事件命名(uncaughtException 与 onerror)。
2021-03-23 10:40:17

一些库有自己的 API 来执行此操作。一些浏览器会报告未处理的拒绝(迟早)。

事实上,done可能根本不会做你想做的。这就是为什么它不是规范的一部分。无论如何,你还是要记得调用它。

没有可靠的、跨平台、跨库的方式来做到这一点。

uncaught 库可以帮助您捕获未处理的Promise拒绝。

它也处理未捕获的错误。

编辑

<script type="text/javascript" src=".../uncaught/lib/index.js"></script>

<script type="text/javascript">
    uncaught.start();
    uncaught.addListener(function (error) {
        console.log('Uncaught error or rejection: ', error.message);
    });
</script>

这种方法的好处是唯一的一个接口,它允许您处理未捕获的错误和未处理的Promise拒绝。

你是对的。这种方法的基础没有什么特别之处。它只是简化unhandledrejectionerror事件使用。
2021-03-30 10:40:17
但它基于相同的unhandledrejection 事件,所以支持的浏览器有:Google Chrome 49+、Opera 41+、Yandex.Browser 16+。
2021-04-04 10:40:17