Search code examples
webpackecmascript-6babeljsbabel-polyfillraygun

babel polyfill catches my errors in place of letting bubble them


I'm using raygun to keep track of my front-end errors. Raygun exploits the EventError by hooking on the window.onerror property. So far so good.

My application is written in ES6 and it uses generators. I use babel to write ES6 web browser compliant code and webpack to bundle it. Since I'm using generators I also import Babel polyfill in my HTML along with my entry chunk. I'm not importing it into my application because the HTML page could load other applications, which in turn could try to run the polyfill. That way, just a polyfill instance is run.

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

To make sure window.onerror works, I had first wrote my own error handler (well, I had copied it from 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;
};

so, by running my code, I would expect a wonderful vintage alert.

Unfortunately, what I get is a message on my error log, but window.onerror hook does not catch it:

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

while if I move my throw new Error('test'); outside my generator function, I get the expected alert. How can I avoid this behavior?


Solution

  • It seems like errors thrown inside your generator happen from a promise context, and unhandled promise rejections are handled differently from uncaught sync errors.

    To catch an uncaught promise rejection you can use the following, for example:

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

    With some older polyfills or older native promises you may have to do the following instead:

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