当前位置: 首页 > 知识库问答 >
问题:

处理猫鼬验证错误-在哪里以及如何处理?

越俊艾
2023-03-14

我正试图决定如何处理猫鼬中的验证错误。

我使用节点验证器定义了自己的验证规则,例如:

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 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允许您根据需要定义字段:

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

这将生成一条错误消息,如下所示:

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

感觉这些验证器似乎希望您使用他们内置的错误消息。例如,我想将一个字段声明为必需,如上所述,但我找不到自定义错误消息的方法。猫鼬验证器模块直到最近才支持自定义消息,这让我认为它们是模型级别的反模式。

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

共有3个答案

江航
2023-03-14
匿名用户

来自猫鼬:https://github.com/leepowellcouk/mongoose-validator

错误消息自定义错误消息现在回到0.2.1中,可以通过options对象进行设置:

验证({message:“字符串应该在3到50个字符之间”},'len',3,50)

我是如何实现的:

var emailValidator = [validate({message: "Email Address should be between 5 and 64 characters"},'len', 5, 64), validate({message: "Email Address is not correct"},'isEmail')];

var XXXX = new Schema({
email : {type: String, required: true, validate: emailValidator} }); 

我的前端处理必需的,所以我从来没有期望猫鼬“必需的”错误会出现在用户面前,更像是后端的安全卫士。

梁存
2023-03-14

我知道验证器插件可能很有用,但我认为mongoose验证的东西比它真正复杂的东西更吓人。从表面上看,这肯定很复杂,但一旦你开始尝试,情况就没那么糟糕了。

如果您查看下面的代码,您将看到如何使用内置验证器返回自定义错误消息的示例。

您所要做的就是在设置字段时使用您自己的自定义错误消息设置第二个参数

检查下面的requiredminlengthmaxlength字段,查看我如何设置自定义错误消息,然后检查以下方法,了解如何访问错误对象或将其发送到前端:

// Grab dependencies:
var mongoose = require('mongoose');

// Setup a schema:
var UserSchema = new mongoose.Schema (
    {
        username: {
            type: String,
            minlength: [2, 'Username must be at least 2 characters.'],
            maxlength: [20, 'Username must be less than 20 characters.'],
            required: [true, 'Your username cannot be blank.'],
            trim: true,
            unique: true,
            dropDups: true,
        }, // end username field
    },
    {
        timestamps: true,
    },
);

// Export the schema:
module.exports = mongoose.model('User', UserSchema);

以上内容将我们的字段设置为具有自定义错误消息。但我们如何访问它们或将其发送到前端?我们可以在服务器控制器中设置以下方法,其响应数据发送回angular:

var myControllerMethods = {
    register : function(req, res) {
        // Create a user based on the schema we created:
        User.create(req.body)
            .then(function(newUser) {
                console.log('New User Created!', newUser);
                res.json(newUser);
            })
            .catch(function(err) {
                if (err.name == 'ValidationError') {
                    console.error('Error Validating!', err);
                    res.status(422).json(err);
                } else {
                    console.error(err);
                    res.status(500).json(err);
                }
            })
    },
};

如果您运行了上面的代码,并且我们的任何mongoose验证器都没有通过,那么错误(err)对象将被抓取。promise中的catch()。如果您将此错误记录在控制台日志中,您将在该对象中看到我们的自定义消息,这取决于标记的错误。

注意:上面的示例只是为了将自定义验证消息添加到Mongoose拥有的已经内置的验证中(例如requiredminlengthmaxlength等等)。

如果您想创建更高级的验证,例如根据正则表达式模式等验证字段,那么您必须创建自定义validator函数。

请参阅此链接上的“自定义验证器”部分,了解如何将验证器直接添加到您的字段中:http://mongoosejs.com/docs/validation.html.

注意:您也可以使用“预保存挂钩”和“实例方法”,但这超出了本问题的范围,内置验证器和“自定义验证器”(前面提到的链接)是更容易的路由。

希望这有帮助!

冯驰
2023-03-14

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

您不希望您的模型处理错误消息。表示层(控制器?)应该依赖类型来决定哪个是要显示的最佳用户友好消息(考虑国际化)。

也有可能通过使用中间件进行验证的情况。在这种情况下,将出现在您的控制器上的错误消息是您传递给Next()回调的任何消息。

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

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();
});

这样,即使验证错误源于中间件,也可以保证一致的验证错误处理。

为了正确地将错误消息与类型匹配,我将创建一个枚举,作为所有可能类型的静态映射:

// 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);

    }
  });
});
 类似资料:
  • 问题内容: 我正在使用Restify和Mongoose创建一个API ,而这两个都是我的新手。我似乎无法找出正确的方法来处理Mongoose / Node中的错误。 到目前为止,我正在尝试执行以下操作: 我正在尝试为此调用GET(针对不存在的用户)。而不是发送回简单的错误消息,而是导致整个节点应用程序失败。我对return next(err)的用户以及应该怎么做感到困惑。 任何帮助是极大的赞赏。

  • 问题内容: 我在桌面应用程序中使用spring + hibernate。 我正在尝试使用分层实现来构建它,所以我有: GUI层–call- >服务层–call-> DAO层 一个更好地说明我的情况的小例子: 问题是:谁抛出异常并由谁处理? 我认为DAO必须抛出第一个异常,然后服务层将其抛出,最后GUI层处理该异常,这样我才能向用户显示消息,这很好吗?有没有一种方法可以使用spring构建一些Exc

  • 如果传入的请求是AJAX请求,则不会生成重定向。相反,带有422状态码的HTTP响应将返回到浏览器,其中包含验证错误的JSON表示。 这不管用!我试图通过ajax请求访问路由,它会重定向回来。 如果验证通过,代码将继续正常执行。但是,如果验证失败,将抛出一个Illumate\合同\验证\验证异常。自动捕获此异常,并生成重定向到用户先前的位置。验证错误甚至会自动Flink到会话! 现在我想知道lar

  • 问题内容: 我试图用mongoose在mongodb中保存一个新文档,但是即使我提供电子邮件,passwordHash和用户名,我也能得到。 这是用户架构。 这就是我创建和保存用户对象的方式。 那么为什么猫鼬会返回验证错误,我不能用作临时值吗? 问题答案: 回应您的最后评论。 您正确的认为null是一个值类型,但是null类型是一种告诉解释器它 没有value的方法 。因此,必须将这些值设置为任何

  • 问题内容: 我正在从npm 使用此架构: 如果我尝试保存已经存在于db中的电子邮件,则如果省略该字段,我希望得到一个类似的电子邮件。但是事实并非如此,我得到了。 这不是验证错误(即使我删除了unique:true也会发生)。 知道为什么吗? 问题答案: 我更喜欢将其放在路径验证机制中,例如 然后,它将被包装,并在您调用或时作为第一个参数返回。

  • 我正在与节点JS中的promise模式作斗争 我在db中寻找用户,然后用用户引用保存新实体,但当用户不在db中时,我应该返回拒绝,但我不确定如何正确地做到这一点。 有什么办法可以做得更好吗? btw:对不起,coffeescript :-[