Node.js Sequelize验证程序一次只返回一个错误
使用Sequelize在数据库中创建或更新项目时,我发现验证器一次只返回一个验证错误 这并不理想,因为我希望在用户提交包含多个错误的表单时将所有错误返回给用户 这是我的模型:Node.js Sequelize验证程序一次只返回一个错误,node.js,orm,sequelize.js,Node.js,Orm,Sequelize.js,使用Sequelize在数据库中创建或更新项目时,我发现验证器一次只返回一个验证错误 这并不理想,因为我希望在用户提交包含多个错误的表单时将所有错误返回给用户 这是我的模型: module.exports = (Sequelize, DataTypes) => { const User = Sequelize.define( 'user', { email: { type: DataTypes.STRING, allowNul
module.exports = (Sequelize, DataTypes) => {
const User = Sequelize.define(
'user',
{
email: {
type: DataTypes.STRING,
allowNull: false,
unique: {
args: true,
msg: 'That email is not available.'
},
validate: {
isEmail: {
args: true,
msg: 'Please enter a valid email.'
}
}
},
username: {
type: DataTypes.STRING,
allowNull: false,
notEmpty: true,
unique: {
args: true,
msg: 'That username is not available.'
},
validate: {
min: {
args: USER_USERNAME_MIN_LENGTH,
msg: 'Please choose a longer username.'
},
max: {
args: USER_USERNAME_MAX_LENGTH,
msg: 'Please choose a shorter username.'
},
is: {
args: /^[0-9a-zA-Z](\/?[a-zA-Z0-9-_])*\/?$/i,
msg: 'Please enter a valid username.'
}
}
}
},
{
underscored: true,
}
);
return User;
};
这是我的控制器(在本例中,我试图更新一个用户,比如说,user 1
,并修改其username
和email
的值,这恰好与另一个用户的值相同,比如user 2
)
因此,您希望验证器为电子邮件
和用户名
字段返回错误,因为它违反了唯一
标志
然而,这就是我在catch
块中得到的:
{ SequelizeUniqueConstraintError: That username is not available.
at Query.formatError (/site/node_modules/sequelize/lib/dialects/postgres/query.js:325:18)
at query.catch.err (/site/node_modules/sequelize/lib/dialects/postgres/query.js:86:18)
at tryCatcher (/site/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/site/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/site/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/site/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/site/node_modules/bluebird/js/release/promise.js:689:18)
at Async._drainQueue (/site/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (/site/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues [as _onImmediate] (/site/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:763:18)
at tryOnImmediate (timers.js:734:5)
at processImmediate (timers.js:716:5)
at process.topLevelDomainCallback (domain.js:101:23)
name: 'SequelizeUniqueConstraintError',
errors:
[ ValidationErrorItem {
message: 'That username is not available.',
type: 'unique violation',
path: 'username',
value: 'bob',
origin: 'DB',
instance: [user],
validatorKey: 'not_unique',
validatorName: null,
validatorArgs: [] } ],
fields: { username: 'bob' },
parent:
{ error: duplicate key value violates unique constraint "users_username_key"
at Connection.parseE (/site/node_modules/pg/lib/connection.js:545:11)
at Connection.parseMessage (/site/node_modules/pg/lib/connection.js:370:19)
at Socket.<anonymous> (/site/node_modules/pg/lib/connection.js:113:22)
at Socket.emit (events.js:127:13)
at Socket.emit (domain.js:421:20)
at addChunk (_stream_readable.js:269:12)
at readableAddChunk (_stream_readable.js:256:11)
at Socket.Readable.push (_stream_readable.js:213:10)
at TCP.onread (net.js:598:20)
name: 'error',
length: 204,
severity: 'ERROR',
code: '23505',
detail: 'Key (username)=(bob) already exists.',
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: 'public',
table: 'users',
column: undefined,
dataType: undefined,
constraint: 'users_username_key',
file: 'nbtinsert.c',
line: '434',
routine: '_bt_check_unique',
sql: 'UPDATE "users" SET "username"=\'bob\',"email"=\'me@aol.com\',"updated_at"=\'2018-03-28 19:26:27.341 +00:00\' WHERE "id" = 2' } ...
{SequelizeUniqueConstraintError:该用户名不可用。
at Query.formatError(/site/node_modules/sequelize/lib/dialogs/postgres/Query.js:325:18)
在query.catch.err(/site/node\u modules/sequelize/lib/dialogs/postgres/query.js:86:18)
在tryCatcher(/site/node_modules/bluebird/js/release/util.js:16:23)
在Promise.\u结算PromiseFromHandler(/site/node\u modules/bluebird/js/release/Promise.js:512:31)
在Promise.\u结算Promise(/site/node\u modules/bluebird/js/release/Promise.js:569:18)
在Promise.\u结算Promise0(/site/node\u modules/bluebird/js/release/Promise.js:614:10)
在承诺中。_结算承诺(/site/node_modules/bluebird/js/release/Promise.js:689:18)
在Async.\u drainQueue(/site/node\u modules/bluebird/js/release/Async.js:133:16)
在Async.\u drainQueues(/site/node\u modules/bluebird/js/release/Async.js:143:10)
在Immediate.Async.drainQueues[as _onImmediate](/site/node\u modules/bluebird/js/release/Async.js:17:14)
运行回调时(timers.js:763:18)
在tryOnImmediate(timers.js:734:5)
在processImmediate(timers.js:716:5)
在process.topLevelDomainCallback(domain.js:101:23)
名称:“SequelizeUniques”,
错误:
[验证错误]{
消息:“该用户名不可用。”,
类型:“唯一冲突”,
路径:“用户名”,
值:“bob”,
来源:“DB”,
实例:[用户],
validatorKey:'非唯一',
验证器名称:null,
validatorArgs:[]}],
字段:{username:'bob'},
起源:
{错误:重复的键值违反唯一约束“users\u username\u key”
在Connection.parseE(/site/node_modules/pg/lib/Connection.js:545:11)
在Connection.parseMessage(/site/node_modules/pg/lib/Connection.js:370:19)
在插座上。(/site/node_modules/pg/lib/connection.js:113:22)
在Socket.emit(events.js:127:13)
位于Socket.emit(domain.js:421:20)
在addChunk(_stream_readable.js:269:12)
在readableAddChunk(_stream_readable.js:256:11)
在Socket.Readable.push(_stream_Readable.js:213:10)
在TCP.onread(net.js:598:20)
名称:“错误”,
长度:204,
严重性:“错误”,
代码:“23505”,
详细信息:“密钥(用户名)=(bob)已存在。”,
提示:未定义,
位置:未定义,
内部位置:未定义,
internalQuery:未定义,
其中:未定义,
架构:“公共”,
表:“用户”,
列:未定义,
数据类型:未定义,
约束:“用户\用户名\密钥”,
文件:“nbtinsert.c”,
行:“434”,
例行程序:“'u bt\u check\u unique',
sql:“更新”用户“设置”用户名“=\'bob\”,“电子邮件”=\'me@aol.com\“,”更新地址为“=\'2018-03-28 19:26:27.341+00:00\”,其中“id”=2'}。。。
我截断了它的其余部分,但正如您所看到的,它只返回用户名的错误。当我修复该错误,然后再次提交表单时,我才得到电子邮件地址的验证错误。我也有同样的问题
如果在属性上设置了allowNull:false
约束,并且该属性的字段为null,则将跳过所有验证器,并抛出ValidationError。因此,首先逐个检查db约束,然后执行常规验证,所有错误将按预期返回到数组中
是对上述问题的引用我也遇到了同样的问题,你解决了吗?我也很好奇这个问题是否得到了解决。使用自定义的isUnique验证函数调用用户名和电子邮件地址的find/findOne方法。不必使用findOne方法就可以完成吗?我想要所有的错误,而不是JU没有一个错误。我有相同的问题,这不是我的问题。我有两个字段(用户名和电子邮件)两者都有非空和唯一约束,我在尝试创建模型和实例时为两者传递非空值,并且我只返回第一个验证错误。正如OP所述,如果我通过将其更改为未使用的值来修复该错误,则会返回下一个验证错误。在我的情况下,问题是是否误解了验证器和约束之间的区别,并期望约束的行为类似于验证器(即返回多个故障,在本例中是唯一的约束,在一个抛出的错误中)。对于其他被这个术语绊倒的人来说,记住区别的一个相当简单的方法是,验证器发生在对DB执行任何SQL之前。约束(唯一、非空等)几乎映射到它们的实际DB表示形式。以下是触发我上述“啊哈!”时刻的文档:
{ SequelizeUniqueConstraintError: That username is not available.
at Query.formatError (/site/node_modules/sequelize/lib/dialects/postgres/query.js:325:18)
at query.catch.err (/site/node_modules/sequelize/lib/dialects/postgres/query.js:86:18)
at tryCatcher (/site/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/site/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/site/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/site/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/site/node_modules/bluebird/js/release/promise.js:689:18)
at Async._drainQueue (/site/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (/site/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues [as _onImmediate] (/site/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:763:18)
at tryOnImmediate (timers.js:734:5)
at processImmediate (timers.js:716:5)
at process.topLevelDomainCallback (domain.js:101:23)
name: 'SequelizeUniqueConstraintError',
errors:
[ ValidationErrorItem {
message: 'That username is not available.',
type: 'unique violation',
path: 'username',
value: 'bob',
origin: 'DB',
instance: [user],
validatorKey: 'not_unique',
validatorName: null,
validatorArgs: [] } ],
fields: { username: 'bob' },
parent:
{ error: duplicate key value violates unique constraint "users_username_key"
at Connection.parseE (/site/node_modules/pg/lib/connection.js:545:11)
at Connection.parseMessage (/site/node_modules/pg/lib/connection.js:370:19)
at Socket.<anonymous> (/site/node_modules/pg/lib/connection.js:113:22)
at Socket.emit (events.js:127:13)
at Socket.emit (domain.js:421:20)
at addChunk (_stream_readable.js:269:12)
at readableAddChunk (_stream_readable.js:256:11)
at Socket.Readable.push (_stream_readable.js:213:10)
at TCP.onread (net.js:598:20)
name: 'error',
length: 204,
severity: 'ERROR',
code: '23505',
detail: 'Key (username)=(bob) already exists.',
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: 'public',
table: 'users',
column: undefined,
dataType: undefined,
constraint: 'users_username_key',
file: 'nbtinsert.c',
line: '434',
routine: '_bt_check_unique',
sql: 'UPDATE "users" SET "username"=\'bob\',"email"=\'me@aol.com\',"updated_at"=\'2018-03-28 19:26:27.341 +00:00\' WHERE "id" = 2' } ...