Jesse
Jesse

Reputation: 432

Bluebird.js: Re-Throwing the error in catch callback is not caught again

I'm wondering why the outer catch callback is never called in this example:

var returnPromise = function () {
  return new Promise(function (resolve, reject) {
      resolve('promise return value');
  })
};
returnPromise().then(function () {
    returnPromise().then(function() {
        throw new Error('hello');
    }).catch(function (err) {
        console.log('got inner error', err);
        return Promise.reject(err);
        //throw err;
    });
}).catch(function (err) {
  console.log('got outer error', err);
});

I tried to throw the caught error again and also to return a rejected Promise but in both cases the outer callback is not called.

Can anyone tell me why?

Live Example using bluebird.js 3.0.2: http://codepen.io/jjd/pen/wMqEpR?editors=001

EDIT: I forgot to return returnPromise() in line 7, that's why the code doesn't work as expected.

Upvotes: 3

Views: 3806

Answers (2)

Solominh
Solominh

Reputation: 2908

Thank to @Tomalak that i understand the problem now. Throw error inside then() will return Promise.reject(err) automatically Promise.reject() inside then() will not return this Promise.reject() automatically. we must return Promise.reject() explicitly

// Caught
Promise.resolve(10)
  .then(() => {
    throw new Error("hello"); // Auto return a reject promise
  })
  .catch(err => {
    console.log(err);
  });

// Uncaught error
Promise.resolve(10)
  .then(() => {
    Promise.reject("hello"); // Error happens => no catch happen
  })
  .catch(err => {
    console.log(err);
  });

// Caught
Promise.resolve(10)
  .then(() => {
    return Promise.reject("hello"); // Explicit return Promise.reject()
  })
  .catch(err => {
    console.log(err);
  });

Upvotes: 0

Tomalak
Tomalak

Reputation: 338306

A rejected promise is not an error. You can turn an error into a rejected promise - and that's what you do in:

.catch(function (err) {
    return Promise.reject(err);
});

and after that it's no longer an error condition. If you want an error condition, don't catch and reject.

function returnPromise() {
    return Promise.resolve('promise return value');
}

returnPromise().then(function () {
    return returnPromise().then(function () {
        throw new Error("failed");
    })
}).catch(function (err) {
    console.error("Outer: " + err);
});

If your catch handler just does some logging and you want to keep the error then simply rethrow it.

returnPromise().then(function () {
    return returnPromise().then(function () {
        throw new Error("failed");
    }).catch(function (err) {
        console.error("Inner: " + err);
        throw err;  // or new Error('...')
    });
}).catch(function (err) {
    console.error("Outer: " + err);
});

Upvotes: 8

Related Questions