从Mongoose预中间件抛出自定义错误并使用Bluebird承诺

时间:2015-02-13 22:48:57

标签: node.js mongoose promise bluebird

我正在使用Mongoose和Bluebird的承诺。我试图在验证预中间件中抛出一个自定义错误,并将其与Bluebird catch一起捕获。

这是我的预验证方法

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;

我在控制器中使用以下内容调用保存

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

这会导致.catch()出现如下错误:

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

我有没有办法让自定义错误传递给catch?我想要这样我可以检查错误类型,并让控制器在响应中回复相应的消息。

1 个答案:

答案 0 :(得分:1)

User.DuplicateEmailError.prototype = Error.prototype;

错了,应该是

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

或者更好地使用

   var util = require("util");

   ...

   util.inherits(User.DuplicateEmailError, Error);