我有两个文件,一个是api.js,另一个是handler.js。对于模式处理,我使用庆祝模块@hapi/joi
在 api.js 上我只写了 API 名称
在 handler.js 上,我编写了 API 功能。
api.js
//JOI Schema Validator Middleware.
router.use(celebrate({
body: Joi.object().keys({
post: Joi.string().max(10),
userid: Joi.string(),
})
}));
const handler = require('./handler');
router.post('/createpost', handler.createPost);
router.use(errors());
module.exports = router;
如果发生错误,我会得到这样的响应
{"statusCode":400,"error":"Bad Request","message":"child \"post\" fails because [\"post\" length must be less than or equal to 10 characters long]","validation":{"source":"body","keys":["post"]}}
我只想将此错误转换为我自己的格式错误,即类似这样的内容
{error: true, status: 500, message: 'validation error', version: x.x.2}
默认的joi错误是通过
router.use(errors());
这个模块产生的。我如何修改这个?
非常感谢任何帮助或建议。
你现在可能已经设法改变了它,但就像我一样,我遇到了完全相同的问题并找到了这个没有答案的帖子。
好吧,对于未来的读者来说,庆祝错误()只不过是一个函数,更确切地说,这个函数:
(err, req, res, next) => {
// If this isn't a Celebrate error, send it to the next error handler
if (!isCelebrate(err)) {
return next(err);
}
const {
joi,
meta,
} = err;
const result = {
statusCode: 400,
error: 'Bad Request',
message: joi.message,
validation: {
source: meta.source,
keys: [],
},
};
if (joi.details) {
for (let i = 0; i < joi.details.length; i += 1) {
const path = joi.details[i].path.join('.');
result.validation.keys.push(EscapeHtml(path));
}
}
return res.status(400).send(result);
}
在那里,您可以看到正在声明的响应对象“result”以及它是如何完成的。所以,要改变它的输出,你必须不使用错误()和创建你自己的函数来处理它。
所以,我声明了一个新函数:
private errorHandling = (err, req, res, next) => {
if (isCelebrate(err)) {
return res.send({
statusCode: 400,
message: err.joi.message
});
}
return next(err);
}
您显然可以更改以上内容以满足您的需要。
Celebrate 将错误结构更改为 CelebrateError,现在您需要使用以下方法访问错误详细信息:
const errorBody = err.details.get('body'); // 'details' is a Map()
const { details: [errorDetails] } = errorBody;
而不是
err.joi
。消息属性保持不变。
然后,我没有使用
app.use(errors())
,而是使用了 app.use(this.errorHandling)
,现在我得到了我想要的格式的庆祝响应。
经过一些研究,我发现它可以通过两种方式解决:
[Segments.BODY]: Joi.object().keys({
value: Joi.string().required().error(new Error('Value is required and has to be a text!')),
})
或
[Segments.BODY]: Joi.object().keys({
password: Joi.string().required().pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')).min(8).label('Password').messages({
'string.pattern.base': 'Your {#label} does not matche the suggested pattern',
'string.base': `Your {#label} should match the suggested pattern`,
'string.empty': `Your {#label} can not be empty`,
'string.min': `Your {#label} has to be at least {#limit} chars`,
'any.required': `Your {#label} is required`,
}),
})