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

如何在zod-openapi的Swagger中展示Zod校验错误及问题排查

问题修复方案

一、Zod校验错误无法在OpenAPI/Swagger界面展示的修复

问题原因

Swagger UI仅会展示OpenAPI文档中明确定义的响应结构,当前接口只配置了201成功响应,未定义400错误响应;同时Zod错误的返回格式也未在OpenAPI Schema中注册,导致Swagger无法识别并展示错误内容。

修复步骤

  1. 定义Zod错误的OpenAPI Schema
    在Schema文件中新增ZodError的结构定义,并注册到registry:

    // data/schemas.ts 或单独的错误Schema文件
    import { z } from 'zod';
    import { registry } from '@/utils/registry';
    
    export const zodErrorSchema = z.object({
      name: z.string(),
      message: z.string(),
      issues: z.array(z.object({
        code: z.string(),
        expected: z.string(),
        received: z.string().nullable(),
        path: z.array(z.string()),
        message: z.string()
      }))
    });
    
    registry.register('ZodError', zodErrorSchema);
    
  2. 在接口中添加400错误响应定义
    修改create-user.ts中的createUserRoute,在responses里新增400状态码的响应配置:

    export const createUserRoute = registry.registerPath({
      // 其他配置保持不变...
      responses: {
        201: {
          content: {
            'application/json': {
              schema: createUserSchema.response,
            },
          },
          description: '用户创建成功',
        },
        400: {
          content: {
            'application/json': {
              schema: { $ref: '#/components/schemas/ZodError' },
            },
          },
          description: '请求参数校验失败',
        },
      },
    });
    
  3. 验证返回格式匹配
    当前makeError函数返回的错误格式已与上述zodErrorSchema一致,无需修改。测试时在Swagger中发送无效请求,即可看到结构化的Zod错误信息。

二、可空字段仅传first_name仍报错的修复

问题原因

Zod的nullable()仅允许字段值为null,但不允许字段不存在(即undefined)。若需求是允许字段可选(可以不传),需使用optional()修饰符,而非仅用nullable()。

修复步骤

修改userSchema中first_name和last_name的定义,结合需求选择合适的修饰符:

// data/users/schema.ts
import { z } from 'zod';

export const userSchema = z.object({
  // 其他字段...
  // 允许不传、传null、传有效字符串
  first_name: z.string().nullable().optional(),
  last_name: z.string().nullable().optional(),
});
  • 若仅需允许字段可选(可以不传),不需要接受null值,直接用z.string().optional()即可;
  • 若需同时允许不传或传null,则用z.string().nullable().optional()。

修改后,仅传入first_name时,last_name为undefined,Zod会通过校验。

内容的提问来源于stack exchange,提问作者user19991216

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 15:33:23