我正在尝试验证 Todo 应用程序的 PATCH
请求负载,该应用程序至少应具有 text
或 value
属性。我在 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/