Fastify中AJV验证无法返回请求体多缺失值的独立错误
解决Fastify中AJV验证错误合并为单条消息的问题
要将Fastify返回的合并式验证错误拆分为独立的错误条目,你需要自定义错误处理函数,拦截AJV的验证错误并重新格式化响应结构。以下是具体实现步骤:
核心思路
Fastify默认会把AJV抛出的所有验证错误合并成一条字符串消息,但error对象中包含validation属性——它是一个数组,存储了每个独立的验证错误详情。我们可以通过错误处理器提取这个数组,将其整理为结构化的错误列表返回。
修改后的完整代码
const fastify = require("fastify"); const server = fastify({ ajv: { customOptions: { allErrors: true, // 必须保留,确保捕获所有验证错误 }, }, logger: true, }); const schema = { schema: { body: { type: "object", properties: { data: { type: "array", items: { type: "object", properties: { foo: { type: "string" }, bar: { type: "string" }, }, required: ["foo", "bar"], }, }, }, required: ["data"], }, }, }; server.post("/", schema, function (request, reply) { console.log({ request: { body: JSON.stringify(request.body), }, }); reply.send({ message: "hello" }); }); // 自定义错误处理函数 server.setErrorHandler((error, request, reply) => { // 判断是否为验证错误 if (error.validation) { reply.status(400).send({ statusCode: 400, error: "Bad Request", message: "验证失败", errors: error.validation.map(err => ({ field: err.instancePath.replace(/^\//, ""), // 去除开头斜杠,简化字段路径 message: err.message })) }); } else { // 非验证错误按默认逻辑处理 reply.send(error); } }); server.listen(3000, function (err, address) { if (err) { server.log.error(err); process.exit(1); } console.log(`server listening on ${address}`); });
效果演示
当你发送包含多个错误的请求体:
{ "data":[{"bar": "bar exists, foo missing"}, {}] }
服务器将返回结构化的错误列表:
{ "statusCode": 400, "error": "Bad Request", "message": "验证失败", "errors": [ { "field": "data/0", "message": "should have required property 'foo'" }, { "field": "data/1", "message": "should have required property 'foo'" }, { "field": "data/1", "message": "should have required property 'bar'" } ] }
关键说明
allErrors: true必须保留:这是AJV捕获所有验证错误的前提,默认情况下AJV只会返回第一个错误。- 错误格式化逻辑:你可以根据需求调整
errors数组的结构,比如将field改为body.data[0]的风格,或者添加错误类型等额外信息。
内容的提问来源于stack exchange,提问作者Leela Venkatesh K
相关产品推荐
相关产品推荐

