0

With Q.js I can trigger window.onerror using .done():

window.onerror = function() {
    console.log('error from handler');
}
var q = Q('initValue').then(function (data) {
    throw new Error("Can't do something and use promise.catch method.");
});
q.catch(function(error){
    throw new Error("This last exception will trigger window.onerror handler via done method.");
})
.done();

In native Promise (ES6) we have no .done(), and last ".catch" is the end of chain:

var p = new Promise(function () {
    throw new Error("fail");
});
p.catch(function (error) {
    throw new Error("Last exception in last chain link");
});

"throw new Error(...)" in ".catch" is one of the simplest way to reproduce runtime error. In reality, it may be another analog of runtime error (EvalError, SyntaxError, TypeError, etc.), e.g.:

var a = [];
a(); // Uncaught TypeError: a is not a function

.done usage is an example to explain my target more detail. I haven't a goal to duplicate .done API.

My task is: I have a promises chain and handler on window.onerror. All errors inside chain I can handle by .cath, except runtime error at the end of the chain. When any runtime exception occurs at the end of promise's methods chain, I need to have the triggered handler that was hanged on window.onerror.

The restrictions: only native JS, must use window.onerror.

What is the best way to trigger this global handler via native Promise?

ArtemM
  • 145
  • 2
  • 4
  • 13
  • `.then()` handlers catch exceptions within them and turn them into rejected promises. So, you can't throw an exception and expect it to go all the way you to the top level in ES6 standards promises. – jfriend00 Sep 07 '16 at 18:29
  • 1
    You don't need to trigger any global error event yourself. Just register your error handler for `unhandledPromiseRejection`! – Bergi Sep 07 '16 at 18:52
  • Not sure, maybe [Catch all unhandled javascript promise rejections](http://stackoverflow.com/q/31472439/1048572) is a better dupe target. – Bergi Sep 07 '16 at 18:54
  • 1
    "*must use window.onerror.*" - why? Can't you just use [`window.onunhandledrejection`](https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onunhandledrejection)`= window.onerror`? – Bergi Sep 08 '16 at 10:14
  • @Bergi, Great! It's simple, but not obvious to me. It works exactly the way I was looking for. Thanks! I will investigate process more deeply. One more way with the same results - add final .catch with window.onerror call `.catch(function (error) { window.onerror(); throw error; })` – ArtemM Sep 08 '16 at 12:34
  • 1
    @A.Mikhailov Better make that `.catch(window.onerror)` - passes in the error, and doesn't lead to an extra unhandled rejection. – Bergi Sep 08 '16 at 12:44
  • @Bergi You're right. Thanks for the correction! – ArtemM Sep 08 '16 at 12:55

1 Answers1

2

Throw the error asynchronously:

window.addEventListener('error', function() {
  console.log('error from handler');
});
new Promise(function () {
  throw new Error("fail");
}).catch(function (error) {
  setTimeout(() => {throw new Error("Last exception in last chain link")}, 0);
});
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • 1
    Why not just drop the `catch` and simply register the error handler for the appropriate event? – Bergi Sep 07 '16 at 18:54
  • @Bergi I just copied the `catch` from the question, I would remove it too. About unhandled promise rejection events, are they supported already? – Oriol Sep 07 '16 at 18:58
  • Oriol, Bergi: thanks a lot for your help! I detailed the question and description. I've looked through all referral links and found no answers for this question. Could you look at updated question again, please – ArtemM Sep 08 '16 at 10:10
  • @Oriol, you're right too! Applicable to my request, add catch with asynchronous throwing: `.catch(function (error) { var a = []; a(); // error in last logic chain link }).catch(function (error) { setTimeout(function () {throw error}, 0); });` – ArtemM Sep 08 '16 at 12:49