💎 Zod 4 is now stable!  Read the announcement.
Zod logo

自定義錯誤 (Customizing errors)

在 Zod 中,驗證錯誤以 z.core.$ZodError 類的實例形式呈現。

zod 包中的 ZodError 類是一個子類,實現了一些額外的便捷方法。

$ZodError 的實例包含一個 .issues 數組。每個 issue 都包含一個人類可讀的 message 和有關該問題的其他結構化元數據。

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'
//   }
// ]

每個 issue 都包含一個具有人類可讀錯誤消息的 message 屬性。錯誤消息可以通過多種方式進行自定義。

error 參數

幾乎每個 Zod API 都接受一個可選的錯誤消息。

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

此自定義錯誤將顯示為源自此架構的任何驗證問題的 message 屬性。

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

所有 z 函數和架構方法都接受自定義錯誤。

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 對象。

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 術語中,錯誤自定義函數被稱為 錯誤映射 (error map)。如果發生驗證錯誤,錯誤映射將在解析時運行。

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

注意 — 在 Zod v3 中,message(字串)和 errorMap(函數)有單獨的參數。這些在 Zod 4 中已統一為 error

錯誤映射接收一個上下文對象,您可以使用它根據驗證問題自定義錯誤消息。

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

對於高級情況,iss 對象提供了可用於自定義錯誤的附加信息。

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 的自動完成功能來探索可用屬性。

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 將控制權交給 優先級鏈 中的下一個錯誤映射。)這對於有選擇地自定義某些錯誤消息而不是其他錯誤消息很有用。

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)

要在 每次解析 的基礎上自定義錯誤,請將錯誤映射傳遞給 parse 方法:

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

這比任何架構級別的自定義消息具有 更低的優先級

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

iss 對象是所有可能錯誤類型的一個 區分聯合。使用 code 屬性來區分它們。

有關所有 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 不會在問題中包含輸入數據。這是為了防止無意中記錄潛在的敏感輸入數據。要在每個 issue 中包含輸入數據,請使用 reportInput 標誌:

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 配置設置:

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

全局錯誤消息的優先級 低於 架構級別或每次解析的錯誤消息。

iss 對象是所有可能錯誤類型的一個 區分聯合。使用 code 屬性來區分它們。

有關所有 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 提供了幾個內置的 區域設置 (locales)。這些是從 zod/v4/core 包中導出的。

注意 — 常規 zod 庫會自動加載 en 區域設置。Zod Mini 默認不加載任何區域設置;相反,所有錯誤消息除默認為 Invalid input

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

要延遲加載區域設置,請考慮動態導入:

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。

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

區域設置 (Locales)

以下區域設置可用:

  • ar — Arabic (阿拉伯語)
  • az — Azerbaijani (阿塞拜疆語)
  • be — Belarusian (白俄羅斯語)
  • bg — Bulgarian (保加利亞語)
  • ca — Catalan (加泰羅尼亞語)
  • cs — Czech (捷克語)
  • da — Danish (丹麥語)
  • de — German (德語)
  • en — English (英語)
  • eo — Esperanto (世界語)
  • es — Spanish (西班牙語)
  • fa — Farsi (波斯語)
  • fi — Finnish (芬蘭語)
  • fr — French (法語)
  • frCA — Canadian French (加拿大法語)
  • he — Hebrew (希伯來語)
  • hu — Hungarian (匈牙利語)
  • id — Indonesian (印度尼西亞語)
  • is — Icelandic (冰島語)
  • it — Italian (意大利語)
  • ja — Japanese (日語)
  • ka — Georgian (格魯吉亞語)
  • km — Khmer (高棉語)
  • ko — Korean (韓語)
  • lt — Lithuanian (立陶宛語)
  • mk — Macedonian (馬其頓語)
  • ms — Malay (馬來語)
  • nl — Dutch (荷蘭語)
  • no — Norwegian (挪威語)
  • ota — Türkî (奧斯曼土耳其語)
  • ps — Pashto (普什圖語)
  • pl — Polish (波蘭語)
  • pt — Portuguese (葡萄牙語)
  • ru — Russian (俄語)
  • sl — Slovenian (斯洛文尼亞語)
  • sv — Swedish (瑞典語)
  • ta — Tamil (泰米爾語)
  • th — Thai (泰語)
  • tr — Türkçe (土耳其語)
  • uk — Ukrainian (烏克蘭語)
  • ur — Urdu (烏爾都語)
  • vi — Tiếng Việt (越南語)
  • zhCN — Simplified Chinese (簡體中文)
  • zhTW — Traditional Chinese (繁體中文)
  • yo — Yorùbá (約魯巴語)

錯誤優先級 (Error precedence)

以下是確定錯誤優先級的快速參考:如果定義了多個錯誤自定義,哪一個優先?從 最高到最低 優先級:

  1. 架構級錯誤 (Schema-level error) — 任何「硬編碼」到架構定義中的錯誤消息。
z.string("Not a string!");
  1. 每次解析錯誤 (Per-parse error) — 傳遞給 .parse() 方法的自定義錯誤映射。
z.string().parse(12, {
  error: (iss) => "My custom error"
});
  1. 全局錯誤映射 (Global error map) — 傳遞給 z.config() 的自定義錯誤映射。
z.config({
  customError: (iss) => "My custom error"
});
  1. 區域設置錯誤映射 (Locale error map) — 傳遞給 z.config() 的自定義錯誤映射。
z.config(z.locales.en());

On this page