node.js - 处理 Mongoose 验证错误——在哪里以及如何处理?

标签 node.js validation mongodb mongoose

我正在尝试决定如何处理 Mongoose 中的验证错误。

使用 Node 验证器的自定义错误消息

我使用 node-validator 定义了我自己的验证规则,例如:

UserSchema.path('username')
  .validate(function (username) {
    return validator.check(username).notEmpty()
  }, 'Username cannot be blank')

这将产生如下所示的错误:

  username: 
   { message: 'Validator "Username cannot be blank" failed for path username',
     name: 'ValidatorError',
     path: 'username',
     type: 'Username cannot be blank' },

使用 Mongoose 验证器

但是,node-validator 提供了自己的错误消息。如果我使用 mongoose-validator Node 模块将 node-validator 直接插入到我的架构中,然后我可以直接使用这些错误消息:

var UserSchema = new Schema({
  name: { type: String, validate: [validate('notEmpty')] }
});

这将生成如下所示的错误消息:

  name: 
   { message: 'Validator "String is empty" failed for path name',
     name: 'ValidatorError',
     path: 'name',
     type: 'String is empty' } }

我也可以在这里提供自定义错误消息:

var UserSchema = new Schema({
  name: { type: String, validate: [validate({message: 'Name cannot be blank' }, 'notEmpty')] }
});

Mongoose 必需标志

Mongoose 允许您根据需要定义字段:

var UserSchema = new Schema({
  name: { type: String, required: true }
});

这将生成如下所示的错误消息:

  name: 
   { message: 'Validator "required" failed for path name',
     name: 'ValidatorError',
     path: 'name',
     type: 'required' } }

问题

感觉好像这些验证器想要您使用他们内置的错误消息。例如,我想将一个字段声明为 required,如上所示,但我找不到自定义错误消息的方法。而且 mongoose-validator 模块直到最近才支持自定义消息,这让我认为它们是模型级别的反模式。

实现这些验证器的最佳方式是什么?我应该让他们自己产生错误,然后以某种方式解释它们吗?

最佳答案

在这一点上,相信 mongoose 如何处理错误似乎是合乎逻辑的。

您不希望您的模型处理错误消息。表示层( Controller ?)应该依赖 type 来决定哪个是最好的用户友好消息来显示(考虑 i18n)。

还有可能通过using a middleware 进行验证的情况。 .在这种情况下,将出现在 Controller 上的错误消息是您传递给 next() 回调的任何内容。

因此,对于中间件,虽然没有记录,但为了在您的模型中保持一致的验证 API,您应该直接使用 Mongoose 的 Error 构造函数:

var mongoose = require('mongoose');
var ValidationError = mongoose.Error.ValidationError;
var ValidatorError  = mongoose.Error.ValidatorError;

schema.pre('save', function (next) {
  if (/someregex/i.test(this.email)) {
    var error = new ValidationError(this);
    error.errors.email = new ValidatorError('email', 'Email is not valid', 'notvalid', this.email);
    return next(error);
  }

  next();
});

这样,即使验证错误源自中间件,您也可以确保得到一致的验证错误处理。

为了将错误消息正确匹配到类型,我将创建一个 enum,它将充当所有可能类型的静态映射:

// my controller.js

var ValidationErrors = {
  REQUIRED: 'required',
  NOTVALID: 'notvalid',
  /* ... */
};


app.post('/register', function(req, res){
  var user = new userModel.Model(req.body);

  user.save(function(err){
    if (err) {
      var errMessage = '';

      // go through all the errors...
      for (var errName in err.errors) {
        switch(err.errors[errName].type) {
          case ValidationErrors.REQUIRED:
            errMessage = i18n('Field is required');
            break;
          case ValidationErrors.NOTVALID:
            errMessage = i18n('Field is not valid');
            break;
        }
      }
      res.send(errMessage);

    }
  });
});

关于node.js - 处理 Mongoose 验证错误——在哪里以及如何处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15012250/

相关文章:

php - Laravel 验证在更新相同的唯一值时抛出错误

javascript - 使用本地版本的 node.js 包

node.js - 创建具有两个配置但具有相同插件的 webpack.config

ruby - Ruby 中的 XSD 模式验证

javascript - AngularJS - 无法在动态输入上访问 $valid

mongodb - 无法在名称中包含两个破折号的 mongodb 中删除集合

javascript - 如何使用时区将以毫秒为单位的时间转换为不同的本地时间

javascript - Node.js:删除 Socket.IO 中的用户

PHP Mongo 正则表达式

javascript - Mongoose 按 createdAt 排序