Mongoose唯一验证器的行为与其他验证器不同

时间:2017-01-05 05:21:55

标签: node.js mongodb validation mongoose

在我的用户架构中,我的电子邮件字段定义如下:

...
email: {
    unique: [true, 'A user with that email address exists. The email must be unique.'],
    type: String,
    lowercase: true,
    required: [true, 'A user must have an email address']
},
...

当我在创建用户时将电子邮件留空时,我可以看到模式required: [true, 'A user must have an email address']中定义的cutomised错误消息。但是,如果我选择已被其他用户使用的电子邮件地址,则会收到其他错误,我无法在unique字段unique: [true, 'A user with that email address exists. The email must be unique.']中看到自定义消息。

电子邮件为空时出错(我觉得有用,因为收到错误消息很简单):required注意到我的错误消息用户必须有电子邮件地址。< / p>

Error create { MongooseError: User validation failed
at ValidationError (/Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongoose/lib/error/validation.js:23:11)
at model.Document.invalidate (/Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongoose/lib/document.js:1486:32)
at /Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongoose/lib/document.js:1362:17
at validate (/Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongoose/lib/schematype.js:705:7)
at /Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongoose/lib/schematype.js:742:9
at Array.forEach (native)
at SchemaString.SchemaType.doValidate (/Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongoose/lib/schematype.js:710:19)
at /Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongoose/lib/document.js:1360:9
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
errors: 
   { email: 
      { MongooseError: A user must have an email address
      at ValidatorError (/Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongoose/lib/error/validator.js:24:11)
      at validate (/Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongoose/lib/schematype.js:704:13)
      at /Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongoose/lib/schematype.js:742:9
      at Array.forEach (native)
      at SchemaString.SchemaType.doValidate (/Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongoose/lib/schematype.js:710:19)
      at /Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongoose/lib/document.js:1360:9
      at _combinedTickCallback (internal/process/next_tick.js:67:7)
      at process._tickCallback (internal/process/next_tick.js:98:9)
    message: 'A user must have an email address',
    name: 'ValidatorError',
    properties: [Object],
    kind: 'required',
    path: 'email',
    value: '' } },
message: 'User validation failed',
name: 'ValidationError' }

已使用电子邮件时出错:unique

Error create { MongoError: E11000 duplicate key error collection: stellium-io.users index: email_1 dup key: { : "john@doe.com" }
at Function.MongoError.create (/Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongodb-core/lib/error.js:31:11)
at toError (/Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongodb/lib/utils.js:114:22)
at /Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongodb/lib/collection.js:657:23
at handleCallback (/Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongodb/lib/utils.js:95:56)
at /Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongodb/lib/bulk/unordered.js:465:9
at handleCallback (/Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongodb/lib/utils.js:95:56)
at resultHandler (/Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongodb/lib/bulk/unordered.js:413:5)
at /Users/fleavamini/Projects/stellium/stellium.io/node_modules/mongodb-core/lib/connection/pool.js:455:18
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
name: 'MongoError',
message: 'E11000 duplicate key error collection: stellium-io.users index: email_1 dup key: { : "john@doe.com" }',
driver: true,
code: 11000,
index: 0,
errmsg: 'E11000 duplicate key error collection: stellium-io.users index: email_1 dup key: { : "john@doe.com" }',
getOperation: [Function],
toJSON: [Function],
toString: [Function] }

这是预期的行为吗?我希望能够在unique字段中获取自定义错误,并将其返回给尝试创建新用户对象的用户。

2 个答案:

答案 0 :(得分:1)

唯一性约束完全在MongoDB服务器中处理。当您添加具有重复键的文档时,MongoDB服务器将返回您显示的错误(E11000 ...)

如果要创建自定义错误消息,则必须自己处理这些错误。

像:

schmea.post('save',function(err,doc,next){
      if (err.name === 'MongoError' && err.code === 11000) {
    next(new Error('email must be unique'));
  } else {
    next(error);
  }
});

答案 1 :(得分:1)

Mongoose中的唯一性不是验证参数(如需要),它告诉Mongoose在MongoDB中为该字段创建唯一索引。

唯一性约束完全在MongoDB服务器中处理。当您添加具有重复键的文档时,MongoDB服务器将返回您显示的错误(E11000 ...)。

如果要创建自定义错误消息,则必须自己处理这些错误。 Mongoose文档(搜索“错误处理中间件”)为您提供了有关如何创建自定义错误处理的示例:

schmea.post('save', function(error, doc, next) {
  if (error.name === 'MongoError' && error.code === 11000) {
    next(new Error('email must be unique'));
  } else {
    next(error);
  }
});

或者您可以使用此插件mongoose-unique-validator

(尽管这并没有为您提供唯一性约束失败的特定字段)