Catching custom error not working in Bluebird

2019-02-19 12:13发布

问题:

I am trying to throw and then catch a custom error in a Bluebird promise chain, but I can't get it to catch the custom error. For example:

function login(req, res, next) {
  function LoginError() {}

  return User.where('id', req.body.userId).fetch()
    .then(function (location) {
      if (req.body.password !== location.get('password')) {
        throw new LoginError();
      }

      // returns a promise
      return Subscription.where('userId', location.get('userId')).fetch();
    })
    .then(function (subscription) {
      return res.send(JSON.stringify(subscription));
    })
    .catch(LoginError, function (err) {
      return res.send('Login error');
    })
    .catch(function (err) {
      res.send('Other error: ' + JSON.stringify(err));
    });
}

When the password doesn't match and it throws LoginError, the error is caught in the second catch block, not the catch block for LoginError. What am I doing wrong?

I'm using Express.js, Bluebird, and Bookshelf/Knex where User is a Bookshelf model.

回答1:

Bluebird distinguishes error constructors from predicate functions in a catch by their inheritance:

For a parameter to be considered a type of error that you want to filter, you need the constructor to have its .prototype property be instanceof Error.

Such a constructor can be minimally created like so:

function MyCustomError() {}
MyCustomError.prototype = Object.create(Error.prototype);

You will need to do the same for your LoginError.

Or if you're using ES6, then class LoginError extends Error {}.