node.js - Mongoose 唯一验证器的行为与其他验证器不同

标签 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, '用户必须有电子邮件地址'] 中定义的自定义错误消息。但是,如果我选择已被其他用户使用的电子邮件地址,则会收到不同的错误,我看不到在 unique 字段中定义的自定义消息 unique: [true, 'A具有该电子邮件地址的用户已存在。电子邮件必须是唯一的。']

电子邮件为空时出错(我发现获取错误消息非常有用):required 请注意,我的错误消息用户必须有电子邮件地址是显示。

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 字段中获取自定义错误,并将其返回给尝试创建新用户对象的用户。

最佳答案

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

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

关于node.js - Mongoose 唯一验证器的行为与其他验证器不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41477799/

相关文章:

python - 如何关闭 mongodb python 连接?

javascript - 为什么 mongoose 的 deleteOne 和 findById 对已删除的 id 起作用

node.js - Model.find().toArray() 声称没有 .toArray() 方法

java - 在 Java 中使用多个 XSD 验证 XML

node.js - 有没有办法打包使用 express 和 ejs 的 nodejs 应用程序?

javascript - 如何从 Lambda 中的回调函数返回 json?

java - Spring MVC 表单验证不适用于嵌套的复杂类型

angular - 如何迭代现有的 FormControl 验证器

javascript - 如何欺骗 Node.js 将 .js 文件加载为 ES6 模块?

javascript - 跨平台 JavaScript 单元和系统测试的现状