express - 强制运行 oneOf 验证?

标签 express express-validator

我正在尝试验证 Todo 应用程序的 PATCH 请求负载,该应用程序至少应具有 textvalue 属性。我在 updateTodoValidators 中这样做。这两个属性都是可选的,但至少必须存在一个(因此是 oneOf),并且如果存在的话,它必须像 oneOf 外部的验证器所指示的那样有效。

const validate = (validations) => {
  return async (req, res, next) => {
    await Promise.all(validations.map(validation => validation.run(req)));

    const errors = validationResult(req)
    if (errors.isEmpty()) {
      return next();
    }

    res
      .status(422)
      .json({
        payload: {
          errors: errors.array()
        },
        message: "Validation error/s",
        error: true
      })
  }
}

const updateTodoValidators = [
  oneOf([
    body('text').exists().withMessage('not specified'),
    body('value').exists().withMessage('not specified')
  ]),
  body('text').optional().trim().notEmpty().withMessage('cannot be empty'),
  body('value').optional().isInt({ min: 1 }).withMessage('must be a valid positive number')
]

app.patch('/todos/:id', validate(updateTodoValidators), async (req, res, next) => { /* Route handler implementation */ })

我正在考虑强制运行验证,如 Running validations imperatively [docs] 中所示。出于代码可读性的目的。我发现,如果我有一些涉及 oneOf 的验证,我的 validate() 会抛出 TypeError ,说 validation.run 不是一个函数。下面是详细说明错误的堆栈跟踪:

(node:88997) UnhandledPromiseRejectionWarning: TypeError: validation.run is not a function
    at Promise.all.validations.map.validation (/Users/alejandro/code/Production/server/validators/validate.js:6:64)
    at Array.map (<anonymous>)
    at /Users/alejandro/code/Production/server/validators/validate.js:6:35
    at Layer.handle [as handle_request] (/Users/alejandro/code/Production/server/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/alejandro/code/Production/server/node_modules/express/lib/router/route.js:137:13)
    at loginRequired (/Users/alejandro/code/Production/server/auth/helpers.js:18:24)
    at Layer.handle [as handle_request] (/Users/alejandro/code/Production/server/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/alejandro/code/Production/server/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/alejandro/code/Production/server/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/alejandro/code/Production/server/node_modules/express/lib/router/layer.js:95:5)
(node:88997) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:88997) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

所以,我的问题是:当验证可能涉及一个或多个 oneOf 时,是否有任何方法可以强制运行验证?

最佳答案

我最终手动完成了它。

对两个参数检查执行.run()。然后验证两者的 _errors 属性是否为空。

export const validateTokens = async (req, res, next) => {
  // Check to make sure one of the header tokens is set and a UUID
  const token1 = await header('token1')
    .isUUID()
    .run(req);
  const token2 = await header('token2')
    .isUUID()
    .run(req);

  // Manual oneOf
  if (isEmpty(token1._errors) || isEmpty(token2._errors)) {
    return next();
  }

  // Return error results
  res.status(400).send('Must include either token1 or token2');
};

关于express - 强制运行 oneOf 验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59573378/

相关文章:

node.js - 如何实现已经与 REGISTER 路由配合使用的 Express-validator 来与 Passport 本地登录配合使用?

javascript - 通过结构化 Express 应用程序提供 html 和 javascript

node.js - 当我使用 Node js 设置 404 时,它在我重新加载我的页面时不起作用

node.js - 浏览器中未设置 Express session cookie

node.js - Node/Express JS "Cannot read property ' 用户名'未定义”

node.js - Express-Validator 中的验证

javascript - Express-validator:如果其他字段值为 true,则使字段可选

javascript - 使用快速验证器验证 req.params

javascript - Node.js/ express 邮寄不工作

node.js - 如何在sequelize模型中插入外键