Sequelize验证器一次只返回一个错误

时间:2018-03-29 00:11:01

标签: node.js orm sequelize.js

使用Sequelize在我的数据库中创建或更新项目时,我发现验证程序一次只返回一个验证错误。

这并不理想,因为我想在提交包含多个错误的表单时将所有错误返回给用户。

这是我的模特:

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并修改usernameemail的值,这恰好就是这样与其他用户的确切值相同,例如User 2)。

try {
  const user = await User.findById(req.user.id);
  if (user) {
    const updatedUser = await user.update({
      username: username || req.user.username,
      email: email || req.user.email
    });

    res.status(200).end();
  }
} catch (err) {
  console.log(err);
  return res.status(500).send(getMappedErrors(err));
}

因此,您希望验证程序返回emailusername字段的错误,因为它违反了unique标记。

然而,这是我在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' } ...

我截断了剩下的部分,但正如您所看到的,它只返回用户名的错误。当我修复它,然后再次提交我的表单时,我才会收到电子邮件地址的验证错误。

1 个答案:

答案 0 :(得分:0)

我有同样的问题。

如果在属性上设置了allowNull:false约束,并且该属性的字段为null,则将跳过所有验证器,并引发ValidationError。因此,首先要一个接一个地检查db约束,然后执行常规验证,所有错误均按预期返回到数组中。

Here是对上述内容的引用