6

I realise there are a few questions about preventDefault not working. But my question is about the rather straightforward case where you have an async function and an error is thrown:

throw 'error of some kind';

... and then you want to have a "mopping up" function to catch any and all such errors. This then works as expected:

window.addEventListener('unhandledrejection', function (event) {
    console.log( 'unhandled Promise rejection, event: ', event );

    // event.preventDefault();
});

But if I uncomment the event.preventDefault(), I expect to see the throw message not then get printed as an error to console. But it always does get so printed.

I checked to make sure that event is indeed cancelable in this case. It claims to be so.

PS from my experiments it seems to be that

window.onunhandledrejection = event => {
    ...
};

is just another way of implementing this same listener for this same "unhandledrejection" event. Using event.preventDefault() there doesn't seem to work either.

Edit

After a few experiments I seem to find that the only way I can find to prevent this is to swallow the error (using try...catch) at some point, preferably at the highest async call in the stack (or rather in the sequence of calls of async functions), if that can be determined.

window.addEventListener('unhandledrejection', event => {
  console.log(event.cancelable, event.reason, "unhandled rejection")
  event.preventDefault()
  event.stopPropagation()
  event.stopImmediatePropagation()
  return false
})

async function x() {
  console.log('async')
  throw "async error"
}

x()

new Promise(res => {
  console.log('prom')
  throw "prom error"
})
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
mike rodent
  • 14,126
  • 11
  • 103
  • 157
  • under which browser? works for me under Chrome 81. Post a runnable stack snippet that shows what you mean. note errors like syntax errors are language level, and are not thrown at runtime and so aren't caught – user120242 May 30 '20 at 10:38
  • Thanks. Firefox 72. I'll try to get a snippet out reasonably soon. This is a regular `throw` + string message, as shown above. – mike rodent May 30 '20 at 10:44
  • 3
    Verified on Firefox 76. Straight Promises don't work either. Looks like a bug. Probably should file an issue with Firefox tracker. – user120242 May 30 '20 at 11:14
  • Thanks ... but could you possibly remove that snippet and maybe put it in an answer? Then it could be discussed as an answer. I just tried those propagation commands, and `return false`: nothing seems to work in FF72 anyway. – mike rodent May 30 '20 at 11:26
  • I added those in just to show that preventing bubbling doesn't help. Pretty sure it's just not implemented yet and should be filed as a bug with Mozilla. You've found a bug I think. – user120242 May 30 '20 at 11:37
  • 2
    I reported this as a bug in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1642147 – evilpie May 30 '20 at 20:36
  • 1
    Note that the propagation is correctly stopped: https://jsfiddle.net/udfwe823/ Only the default behavior of logging the error is not prevented. – Kaiido Jun 02 '20 at 08:07
  • @Kaiido Thanks for the fiddle demonstration, useful to know. Is it official that event listeners get fired in the order in which they appear in the code, I wonder? (Not that this makes any difference to the validity of your observation). – mike rodent Jun 02 '20 at 15:35
  • Since here there will not be any bubblong (because the event fires on window) yes, it's specced behavior – Kaiido Jun 02 '20 at 22:33
  • FWIW, in Chrome 92 on Linux it doesn't work for me either. – balu Sep 28 '21 at 19:53
  • @balu did you try running the code snippet? It works fine in Chromium 94 on Linux, but it doesn't work in the console because chrome [is ridiculously strict about cross-origin policy](https://bugs.chromium.org/p/chromium/issues/detail?id=655694) and the devtools cross an origin boundary. – Masklinn Oct 08 '21 at 12:33
  • @Masklinn Huh. Indeed, I tried again and `event.preventDefault()` seems to successfully prevent the error from getting printed to the console in Chrome 92. No idea what I did wrong the first time. – balu Oct 12 '21 at 17:27
  • @balu I mentioned the console because that's exactly the issue I had in trying it: if you copy the code to the developer tools console it will silently fail because of COP restrictions. If you run it as part of a page it works fine. – Masklinn Oct 13 '21 at 05:53

2 Answers2

2

Verified on Firefox 76. Straight Promises don't work either. Looks like a bug. Probably should file an issue with Mozilla's Firefox tracker.
Note: this is not a solution. It's doubtful there is any solution except filing a bug and having it fixed.

window.onerror = msg => console.log(msg) || false

window.addEventListener('unhandledrejection', event => {
  console.log(event.cancelable, event.reason, "unhandled rejection")
  event.preventDefault()
  event.stopPropagation()
  event.stopImmediatePropagation()
  return false
})

async function x() {
  console.log('async')
  throw "async error"
}

x()

new Promise(res => {
  console.log('prom')
  throw "prom error"
})
user120242
  • 14,918
  • 3
  • 38
  • 52
  • Thanks for your help with this. As I said, neither "stop propagation" commands seems to work, nor returning `false`. – mike rodent May 30 '20 at 11:42
0

Repro on Firefox97. It seems the error logs were printed on the console before triggering the 'unhandledrejection' handler so the event.preventDefault() could not help.

ouflak
  • 2,458
  • 10
  • 44
  • 49
Tony
  • 1
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/31209797) – Francisco Puga Mar 10 '22 at 09:01