babel polyfill 捕获我的错误而不是让它们冒泡

babel polyfill catches my errors in place of letting bubble them

我正在使用 raygun 来跟踪我的前端错误。 Raygun 通过挂钩 window.onerror 属性 来利用 EventError。到目前为止一切顺利。

我的应用程序是用 ES6 编写的,它使用生成器。我使用 babel 来编写符合 ES6 网络浏览器的代码,并使用 webpack 来捆绑它。由于我使用的是 generators,因此我还在我的 HTML 中导入了 Babel polyfill 以及我的 entry chunk。我没有将它导入到我的应用程序中,因为 HTML 页面可以加载其他应用程序,而这些应用程序又可以尝试 运行 polyfill。这样,只有一个 polyfill 实例是 运行.

<script src="/container/lib/polyfill.js"></script>
<script src="/container/vendor.bundle.js"></script>
<script src="/container/myApp.js"></script>

为了确保 window.onerror 有效,我首先编写了自己的错误处理程序(嗯,我是从 MDN 复制的):

window.onerror = function (msg, url, lineNo, columnNo, error) {
    var string = msg.toLowerCase();
    var substring = "script error";
    if (string.indexOf(substring) > -1){
        alert('Script Error: See Browser Console for Detail');
    } else {
        var message = [
            'Message: ' + msg,
            'URL: ' + url,
            'Line: ' + lineNo,
            'Column: ' + columnNo,
            'Error object: ' + JSON.stringify(error)
        ].join(' - ');

        alert(message);
    }

    return false;
};

所以,通过 运行 宁我的代码,我期待一个美妙的复古警报。

不幸的是,我得到的是错误日志中的一条消息,但是 window.onerror 钩子没有捕捉到它:

Unhandled promise rejection Error: test
Analisi dello stack:
runApp@webpack:///../index.js?:86:11
initSteps$@webpack:///../index.js?:161:21
tryCatch@http://172.16.0.2/container/lib/polyfill.js:6151:37
invoke@http://172.16.0.2/container/lib/polyfill.js:6442:22
defineIteratorMethods/</prototype[method]@http://172.16.0.2/container/lib/polyfill.js:6203:16
resume@webpack:////Users/matteo/Documents/em3/container/web_src/lib/utils.js?:25:9
initSteps$/<@webpack:///../index.js?:148:25
run@http://172.16.0.2/container/lib/polyfill.js:3911:22
notify/<@http://172.16.0.2/container/lib/polyfill.js:3924:28
flush@http://172.16.0.2/container/lib/polyfill.js:1209:9
MutationCallback*[64]</module.exports@http://172.16.0.2/container/lib/polyfill.js:1228:5
[198]<@http://172.16.0.2/container/lib/polyfill.js:3837:26
s@http://172.16.0.2/container/lib/polyfill.js:1:246
s/<@http://172.16.0.2/container/lib/polyfill.js:1:305
[295]<@http://172.16.0.2/container/lib/polyfill.js:6017:1
s@http://172.16.0.2/container/lib/polyfill.js:1:246
s/<@http://172.16.0.2/container/lib/polyfill.js:1:305
[1]</<@http://172.16.0.2/container/lib/polyfill.js:5:1
[1]<@http://172.16.0.2/container/lib/polyfill.js:2:2
s@http://172.16.0.2/container/lib/polyfill.js:1:246
e@http://172.16.0.2/container/lib/polyfill.js:1:425
@http://172.16.0.2/container/lib/polyfill.js:1:11

而如果我将 throw new Error('test'); 移到生成器函数之外,我会收到预期的警报。我怎样才能避免这种行为?

您的生成器内部抛出的错误似乎是从 promise 上下文中发生的,未处理的 promise 拒绝与未捕获的同步错误的处理方式不同。

要捕获未捕获的承诺拒绝,您可以使用以下命令,例如:

window.addEventListener("unhandledrejection", function (event) {
  console.warn("WARNING: Unhandled promise rejection. Reason: "
               + event.reason);
});

对于一些较旧的 polyfill 或较旧的本机承诺,您可能必须改为执行以下操作:

window.onunhandledrejection = function(event) { ...};