Zod logo

自定义错误

在 Zod 中,验证错误以 z.core.$ZodError 类的实例形式显示。

🌐 In Zod, validation errors are surfaced as instances of the z.core.$ZodError class.

zod 包中的 ZodError 类是一个子类,它实现了一些额外的便利方法。

$ZodError 的实例包含一个 .issues 数组。每个问题包含一个可读的 message 以及关于该问题的额外结构化元数据。

🌐 Instances of $ZodError contain an .issues array. Each issue contains a human-readable message and additional structured metadata about the issue.

import * as z from "zod";
 
const result = z.string().safeParse(12); // { success: false, error: ZodError }
result.error.issues;
// [
//   {
//     expected: 'string',
//     code: 'invalid_type',
//     path: [],
//     message: 'Invalid input: expected string, received number'
//   }
// ]

每个问题都包含一个带有人类可读错误消息的 message 属性。错误消息可以通过多种方式自定义。

🌐 Every issue contains a message property with a human-readable error message. Error messages can be customized in a number of ways.

error 参数

🌐 The error param

几乎所有 Zod API 都接受可选的错误消息。

🌐 Virtually every Zod API accepts an optional error message.

z.string("Not a string!");

此自定义错误将显示为源自此模式的任何验证问题的 message 属性。

🌐 This custom error will show up as the message property of any validation issues that originate from this schema.

z.string("Not a string!").parse(12);
// ❌ throws ZodError {
//   issues: [
//     {
//       expected: 'string',
//       code: 'invalid_type',
//       path: [],
//       message: 'Not a string!'   <-- 👀 custom error message
//     }
//   ]
// }

所有 z 函数和模式方法都接受自定义错误。

🌐 All z functions and schema methods accept custom errors.

z.string("Bad!");
z.string().min(5, "Too short!");
z.uuid("Bad UUID!");
z.iso.date("Bad date!");
z.array(z.string(), "Not an array!");
z.array(z.string()).min(5, "Too few items!");
z.set(z.string(), "Bad set!");

如果你愿意,你也可以传递一个带有 error 参数的 params 对象。

🌐 If you prefer, you can pass a params object with an error parameter instead.

z.string({ error: "Bad!" });
z.string().min(5, { error: "Too short!" });
z.uuid({ error: "Bad UUID!" });
z.iso.date({ error: "Bad date!" });
z.array(z.string(), { error: "Bad array!" });
z.array(z.string()).min(5, { error: "Too few items!" });
z.set(z.string(), { error: "Bad set!" });

error 参数可选择接受一个函数。Zod 术语中,错误自定义函数被称为 错误映射。如果在解析时发生验证错误,错误映射将会运行。

🌐 The error param optionally accepts a function. An error customization function is known as an error map in Zod terminology. The error map will run at parse time if a validation error occurs.

z.string({ error: ()=>`[${Date.now()}]: Validation failure.` });

注意 — 在 Zod v3 中,message(一个字符串)和 errorMap(一个函数)有单独的参数。在 Zod 4 中,这些已统一为 error

错误映射接收一个上下文对象,你可以使用它根据验证问题自定义错误消息。

🌐 The error map receives a context object you can use to customize the error message based on the validation issue.

z.string({
  error: (iss) => iss.input === undefined ? "Field is required." : "Invalid input."
});

对于高级情况,iss 对象提供了可用于自定义错误的额外信息。

🌐 For advanced cases, the iss object provides additional information you can use to customize the error.

z.string({
  error: (iss) => {
    iss.code; // the issue code
    iss.input; // the input data
    iss.inst; // the schema/check that originated this issue
    iss.path; // the path of the error
  },
});

根据你使用的 API,可能会有额外的属性可用。使用 TypeScript 的自动补齐功能来探索可用的属性。

🌐 Depending on the API you are using, there may be additional properties available. Use TypeScript's autocomplete to explore the available properties.

z.string().min(5, {
  error: (iss) => {
    // ...the same as above
    iss.minimum; // the minimum value
    iss.inclusive; // whether the minimum is inclusive
    return `Password must have ${iss.minimum} characters or more`;
  },
});

返回 undefined 以避免自定义错误消息并回退到默认消息。(更具体来说,Zod 将将控制权交给 优先级链 中的下一个错误映射。)这对于有选择地自定义某些错误消息而不修改其他消息非常有用。

🌐 Return undefined to avoid customizing the error message and fall back to the default message. (More specifically, Zod will yield control to the next error map in the precedence chain.) This is useful for selectively customizing certain error messages but not others.

z.int64({
  error: (issue) => {
    // override too_big error message
    if (issue.code === "too_big") {
      return { message: `Value must be <${issue.maximum}` };
    }
 
    //  defer to default
    return undefined;
  },
});

每次解析错误自定义

🌐 Per-parse error customization

要在每次解析时自定义错误,请将错误映射传入解析方法:

🌐 To customize errors on a per-parse basis, pass an error map into the parse method:

const schema = z.string();
 
schema.parse(12, {
  error: iss => "per-parse custom error"
});

这比任何模式级自定义消息的优先级都低

🌐 This has lower precedence than any schema-level custom messages.

const schema = z.string({ error: "highest priority" });
const result = schema.safeParse(12, {
  error: (iss) => "lower priority",
});
 
result.error.issues;
// [{ message: "highest priority", ... }]

iss 对象是所有可能问题类型的 判别联合。使用 code 属性来区分它们。

🌐 The iss object is a discriminated union of all possible issue types. Use the code property to discriminate between them.

有关所有 Zod 问题代码的详细说明,请参阅 zod/v4/core 文档。

const result = schema.safeParse(12, {
  error: (iss) => {
    if (iss.code === "invalid_type") {
      return `invalid type, expected ${iss.expected}`;
    }
    if (iss.code === "too_small") {
      return `minimum is ${iss.minimum}`;
    }
    // ...
  }
});

在问题中包含输入

🌐 Include input in issues

默认情况下,Zod 不会在问题中包含输入数据。这是为了防止意外记录可能包含敏感信息的输入数据。要在每个问题中包含输入数据,请使用 reportInput 标志:

🌐 By default, Zod does not include input data in issues. This is to prevent unintentional logging of potentially sensitive input data. To include the input data in each issue, use the reportInput flag:

z.string().parse(12, {
  reportInput: true
})
 
// ZodError: [
//   {
//     "expected": "string",
//     "code": "invalid_type",
//     "input": 12, // 👀
//     "path": [],
//     "message": "Invalid input: expected string, received number"
//   }
// ]

全局错误自定义

🌐 Global error customization

要指定全局错误映射,请使用 z.config() 设置 Zod 的 customError 配置项:

🌐 To specify a global error map, use z.config() to set Zod's customError configuration setting:

z.config({
  customError: (iss) => {
    return "globally modified error";
  },
});

全局错误消息的优先级低于模式级或每次解析的错误消息。

🌐 Global error messages have lower precedence than schema-level or per-parse error messages.

iss 对象是所有可能问题类型的 判别联合。使用 code 属性来区分它们。

🌐 The iss object is a discriminated union of all possible issue types. Use the code property to discriminate between them.

有关所有 Zod 问题代码的详细说明,请参阅 zod/v4/core 文档。

z.config({
  customError: (iss) => {
    if (iss.code === "invalid_type") {
      return `invalid type, expected ${iss.expected}`;
    }
    if (iss.code === "too_small") {
      return `minimum is ${iss.minimum}`;
    }
    // ...
  },
});

国际化

🌐 Internationalization

为了支持错误信息的国际化,Zod 提供了几个内置的语言环境。它们从 zod/v4/core 包中导出。

🌐 To support internationalization of error message, Zod provides several built-in locales. These are exported from the zod/v4/core package.

注意 — 常规的 zod 库会自动加载 en 语言环境。Zod Mini 默认不加载任何语言环境;相反,所有错误信息默认使用 Invalid input

import * as z from "zod";
import { en } from "zod/locales"
 
z.config(en());

要延迟加载语言环境,请考虑使用动态导入:

🌐 To lazily load a locale, consider dynamic imports:

import * as z from "zod";
 
async function loadLocale(locale: string) {
  const { default: locale } = await import(`zod/v4/locales/${locale}.js`);
  z.config(locale());
};
 
await loadLocale("fr");

为了方便,所有区域设置都从 "zod" 导出为 z.locales。在某些打包工具中,这可能无法进行 tree-shaking。

🌐 For convenience, all locales are exported as z.locales from "zod". In some bundlers, this may not be tree-shakable.

import * as z from "zod";
 
z.config(z.locales.en());

语言环境

🌐 Locales

以下语言环境可用:

🌐 The following locales are available:

  • ar — 阿拉伯语
  • az — 阿塞拜疆语
  • be — 白俄罗斯语
  • bg — 保加利亚语
  • ca — 加泰罗尼亚语
  • cs — 捷克
  • da — 丹麦语
  • de — 德语
  • en — 英语
  • eo — 世界语
  • es — 西班牙语
  • fa — 波斯语
  • fi — 芬兰语
  • fr — 法语
  • frCA — 加拿大法语
  • he — 希伯来语
  • hu — 匈牙利语
  • hy — 亚美尼亚人
  • id — 印度尼西亚语
  • is — 冰岛语
  • it — 意大利语
  • ja — 日语
  • ka — 格鲁吉亚语
  • km — 柬埔寨语
  • ko — 韩语
  • lt — 立陶宛语
  • mk — 马其顿语
  • ms — 马来语
  • nl — 荷兰语
  • no — 挪威语
  • ota — 土耳其语
  • ps — 普什图语
  • pl — 波兰语
  • pt — 葡萄牙语
  • ru — 俄语
  • sl — 斯洛文尼亚语
  • sv — 瑞典语
  • ta — 泰米尔语
  • th — 泰语
  • tr — 土耳其语
  • uk — 乌克兰语
  • ur — 乌尔都语
  • uz — 乌兹别克语
  • vi — 越南语
  • zhCN — 简体中文
  • zhTW — 繁体中文
  • yo — 约鲁巴语

错误优先级

🌐 Error precedence

以下是确定错误优先级的快速参考:如果定义了多个错误自定义,哪个优先?从最高到最低优先级:

🌐 Below is a quick reference for determining error precedence: if multiple error customizations have been defined, which one takes priority? From highest to lowest priority:

  1. 模式级错误 — 任何“硬编码”到模式定义中的错误信息。
z.string("Not a string!");
  1. 每解析错误 — 一个传入 .parse() 方法的自定义错误映射。
z.string().parse(12, {
  error: (iss) => "My custom error"
});
  1. 全局错误映射 — 一个传入 z.config() 的自定义错误映射。
z.config({
  customError: (iss) => "My custom error"
});
  1. 本地错误映射 — 一个传入 z.config() 的自定义错误映射。
z.config(z.locales.en());

On this page