检查mongoose验证错误的最佳方法

zem*_*rco 26 mongoose node.js

我的usermodel 有两个验证函数

User.schema.path('email').validate(function(value, respond) {
  User.findOne({email: value}, function(err, user) {
    if(err) throw err;
    if(user) return respond(false);
    respond(true);
  });
}, 'EMAIL_EXISTS');
Run Code Online (Sandbox Code Playgroud)

同样的 username

User.schema.path('username').validate(function(value, respond) {
  User.findOne({username: value}, function(err, user) {
    if(err) throw err;
    if(user) return respond(false);
    respond(true);
  });
}, 'USERNAME_TAKEN');
Run Code Online (Sandbox Code Playgroud)

它们以下列格式返回错误

{ message: 'Validation failed',
  name: 'ValidationError',
  errors: 
    { username: 
      { message: 'Validator "USERNAME_TAKEN" failed for path username',
        name: 'ValidatorError',
        path: 'username',
        type: 'USERNAME_TAKEN' } } }
Run Code Online (Sandbox Code Playgroud)

email路径的错误类似.是否有更智能的方法来检查这些错误而不是以下?

if (err && err.errors && err.errors.username) { ... }
Run Code Online (Sandbox Code Playgroud)

这有点难看.

Ser*_*món 30

从技术上讲,您必须首先检查错误名称,因为并非所有错误都以相同的方式处理.然后,根据错误名称,您必须检查特定属性,作为ValidationError附带的errors属性.

此外,您将字段名称放在错误类型中,这是多余的,最好使用相同的错误类型,因为在错误检查过程中,您还将获得字段名称.

所以你的代码可能是这样的:

User.schema.path('email').validate(function(value, respond) {
  User.findOne({email: value}, function(err, user) {
    if(err) throw err;
    if(user) return respond(false);
    respond(true);
  });
}, 'exists');

User.schema.path('username').validate(function(value, respond) {
  User.findOne({username: value}, function(err, user) {
    if(err) throw err;
    if(user) return respond(false);
    respond(true);
  });
}, 'exists');
Run Code Online (Sandbox Code Playgroud)

然后,错误检查程序:

if (err) {
  switch (err.name) {
    case 'ValidationError':
      for (field in err.errors) {
        switch (err.errors[field].type) {
          case 'exists':
            ...
            break;
          case 'invalid':
            ...
            break;
          ...
        }
      }
      break;
    default:
      ...
  }
}
Run Code Online (Sandbox Code Playgroud)

如果你想缩短它,你有各种选择.如果您只有一种类型的验证,您可以这样做:

if (err) {
  if (err.name == 'ValidationError') {
    for (field in err.errors) {
      ...
    }
  } else {
    // A general error (db, crypto, etc…)
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

错误检查过程的最小表达式与您在帖子中写的内容类似:

if (err) {
  for (field in err.errors) {
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

这将起作用,因为如果没有定义错误,它将忽略for.但是你在这里忽略了所有其他错误类型.

我也认为这些错误布局有点乱,但不要指望在不久的将来这会改变.

  • ValidationError是一般错误,由几个其他模块抛出,每个模块具有不同的格式和/或属性.最好具体,并在错误检查过程中检查`err instanceof mongoose.Error.ValidationError`. (9认同)

Sud*_*aur 7

只需编写以下代码即可享受.

if (err) {
    console.log('Error Inserting New Data');
    if (err.name == 'ValidationError') {
        for (field in err.errors) {
            console.log(err.errors[field].message); 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)