You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 00:01:20