Adam Duro
Adam Duro

Reputation: 882

Throwing custom errors from Mongoose pre middleware and using Bluebird promises

I am using Mongoose with Bluebird promises. I am trying to throw a custom error in a validate pre middleware and have it catchable with a Bluebird catch.

Here is my pre validate method

schema.pre('validate', function(next) {
  var self = this;

  if (self.isNew) {
    if (self.isModified('email')) {
      // Check if email address on new User is a duplicate
      checkForDuplicate(self, next);
    }
  }

});

function checkForDuplicate(model, cb) {
  User.where({email: model.email}).count(function(err, count) {
    if (err) return cb(err);
    // If one is found, throw an error
    if (count > 0) {
      return cb(new User.DuplicateEmailError());
    }
    cb();
  });
}

User.DuplicateEmailError = function () {
  this.name = 'DuplicateEmailError';
  this.message = 'The email used on the new user already exists for another user';
}
User.DuplicateEmailError.prototype = Error.prototype;

I am calling the save with the following in my controller

User.massAssign(request.payload).saveAsync()
  .then(function(user) {
    debugger;
    reply(user);
  })
  .catch(function(err) {
    debugger;
    reply(err);
  });

This results in the .catch() having an error that looks like this:

err: OperationalError
  cause: Error
  isOperational: true
  message: "The email used on the new user already exists for another user"
  name: "DuplicateEmailError"
  stack: undefined
  __proto__: OperationalError

Is there a way for me to have the custom error be what is delivered to the catch? I want tis so I can check for the error type, and have the controller respond with the appropriate message back in the response.

Upvotes: 1

Views: 581

Answers (1)

Esailija
Esailija

Reputation: 140228

User.DuplicateEmailError.prototype = Error.prototype;

is wrong, it should be

User.DuplicateEmailError.prototype = Object.create(Error.prototype);
User.DuplicateEmailError.prototype.constructor = User.DuplicateEmailError;

Or better use

   var util = require("util");

   ...

   util.inherits(User.DuplicateEmailError, Error);

Upvotes: 1

Related Questions