Andreas Remdt
Andreas Remdt

Reputation: 655

UnhandledPromiseRejectionWarning: undefined in Mongoose

When trying to authenticate users with Mongoose I get the following warning in my console:

(node:20114) UnhandledPromiseRejectionWarning: undefined (node:20114) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) (node:20114) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Trying to trace the stack doesn't result in anything, all I get is undefined. Similar questions exist here on Stackoverflow, but they don't apply to my situation. Any idea what this could cause?

My route controller is calling the findByCredentials function inside the Mongoose model:

Controller

static login(req, res) {
    User.findByCredentials(req.body.email, req.body.password)
      .then(user => {
        return user.generateAuthToken().then(token => {
          res.header("x-auth", token).json(user);
        });
      })
      .catch(error => {
        res.status(400).json({ message: "Invalid credentials." });
      });
  }

Model

userSchema.statics.findByCredentials = function(email, password) {
  return this.findOne({ email }).then(user => {
    if (!user) {
      Promise.reject();
    }
    return new Promise((resolve, reject) => {
      bcrypt.compare(password, user.password, (err, res) => {
        res ? resolve(user) : reject();
      });
    });
  });
};

Upvotes: 0

Views: 3862

Answers (1)

AvcS
AvcS

Reputation: 2323

The error undefined is coming from your Promise.reject() you are not passing any error message to it, so you are literally throwing undefined.

It is not caught in the catch in login, because you are not returning it from your findByCredentials method.

Solution:

userSchema.statics.findByCredentials = function(email, password) {
    return this.findOne({ email }).then(user => {
        if (!user) {
            return Promise.reject('User not available');
        }

        return new Promise((resolve, reject) => {
            bcrypt.compare(password, user.password, (err, res) => {
                res ? resolve(user) : reject();
            });
        });
    });
};

Upvotes: 2

Related Questions