Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Top promise .catch not triggered when returned child promise rejects

I have this:

function sayHello() {
    return new Promise( resolve => {
       throw new Error('reject');
    });
}

new Promise(resolve => sayHello()).then(ok => console.log('ok:', ok)).catch( err => console.error('err:', err) );

However the .catch never triggers. I though if I return a promise within a promise, it gets chained so that top level .then and .catch are re-reouted to child .then and .catch?

like image 280
Noitidart Avatar asked Sep 27 '16 17:09

Noitidart


People also ask

Can you catch a Promise rejection?

If an error condition arises inside a promise, you “reject” the promise by calling the reject() function with an error. To handle a promise rejection, you pass a callback to the catch() function. This is a simple example, so catching the rejection is trivial.

How do you catch a mistake of Promise?

Inside the promise, the catch() method will catch the error caused by the throw statement and reject() . If an error occurs and you don't have the catch() method, the JavaScript engine issues a runtime error and stops the program.

What happens on Promise reject?

The Promise. reject() method returns a Promise object that is rejected with a given reason.

How do you handle rejection promises?

We must always add a catch() , otherwise promises will silently fail. In this case, if thePromise is rejected, the execution jumps directly to the catch() method. You can add the catch() method in the middle of two then() methods, but you will not be able to break the chain when something bad happens.


1 Answers

The problem is with your "new error" thrown at the Promise callback. Throwing an error inside promise executor does not automatically reject it.
Edit: actually Promise executor does automatically reject the promise when an exception is thrown. Nevertheless, this is not the main cause of your problem. Also a note - throwing will only work on the "main" level of executor, so any asynchronous job throwing an exception won't automatically reject the promise.

Another problem spotted - your Promise chain (new Promise(resolve => sayHello())...) is also invalid - you are simply returning a function call result. You always have to manually resolve or reject a Promise that you've created with it's standard constructor (aka. new Promise(executorCallback)).

To fix the other problem, you can use "automatically resolved promise", which I think will do what you are trying to achieve:

Promise.resolve(sayHello()).then(...)

So in the end, your code should look like this (using the gist you have posted in the comment below by answer):

function sayHello() {
    return new Promise( (resolve,reject) => {
       reject('rawr')
    });
}

Promise.resolve(sayHello()).then(ok => console.log('ok:', ok)).catch( err => console.error('err:', err) );
like image 196
mdziekon Avatar answered Oct 23 '22 04:10

mdziekon