Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Promise reject() causes "Uncaught (in promise)" warning

Once a promise reject() callback is called, a warning message "Uncaught (in promise)" appears in the Chrome console. I can't wrap my head around the reason behind it, nor how to get rid of it.

var p = new Promise((resolve, reject) => {
  setTimeout(() => {
    var isItFulfilled = false
    isItFulfilled ? resolve('!Resolved') : reject('!Rejected')
  }, 1000)  
})

p.then(result => console.log(result))
p.catch(error => console.log(error))

Warning:

enter image description here

Edit:

I found out that if the onRejected handler is not explicitly provided to the .then(onResolved, onRejected) method, JS will automatically provide an implicit one. It looks like this: (err) => throw err. The auto generated handler will throw in its turn.

Reference:

If IsCallable(onRejected)` is false, then
     Let onRejected be "Thrower".

http://www.ecma-international.org/ecma-262/6.0/index.html#sec-performpromisethen

like image 863
Yevgeny Kozlov Avatar asked Feb 25 '17 18:02

Yevgeny Kozlov


People also ask

What happens if promise is rejected?

If the Promise rejects, the second function in your first . then() will get called with the rejected value, and whatever value it returns will become a new resolved Promise which passes into the first function of your second then.

Does reject return a promise?

The static Promise. reject function returns a Promise that is rejected. For debugging purposes and selective error catching, it is useful to make reason an instanceof Error .

What is uncaught in promise?

What does that log "Uncaught (in promise)" mean? It means that there was an error in one of our promises, but we did not write any code in order to handle that error and try to catch it.


2 Answers

This happens because you do not attach a catch handler to the promise returned by the first then method, which therefore is without handler for when the promise rejects. You do have one for the promise p in the last line, but not for the chained promise, returned by the then method, in the line before it.

As you correctly added in comments below, when a catch handler is not provided (or it's not a function), the default one will throw the error. Within a promise chain this error can be caught down the line with a catch method callback, but if none is there, the JavaScript engine will deal with the error like with any other uncaught error, and apply the default handler in such circumstances, which results in the output you see in the console.

To avoid this, chain the .catch method to the promise returned by the first then, like this:

p.then( result =>  console.log('Fulfilled'))
 .catch( error =>  console.log(error) );
like image 156
trincot Avatar answered Oct 17 '22 12:10

trincot


Even if you use Promises correctly: p.then(p1).catch(p2) you can still get an uncaught exception if your p2 function eventually throws an exception which you intend to catch using a mechanism like window.onerror. The reason is that the stack has already been unwound by the error handling done in the promise. To fix this, make sure that your error code (called by the reject function) does not throw an exception. It should simply return.

It would be nice if the error handling code could detect that the stack has already been unwound (so your error call doesn't have to have a flag for this case), and if anyone knows how to do this easily I will edit this answer to include that explanation.

like image 1
David Spector Avatar answered Oct 17 '22 13:10

David Spector