Human friendly error messages
In v4 I suggest to make ZodError::message more readable and human friendly by utilizing the already implemented prettifyError() in its getter.
In order to preserve the observability of issues that used to be serialized into snapshots before, I added a custom serializer into vitest configuration.
Related to #4418 and #4424
I also think that those symbols like ❌ and ➡️ are too opinionated, it should be the responsibility of an UI to decide if such icons are required and/or which ones to use. But that could be another PR.
Summary by CodeRabbit
Summary by CodeRabbit
-
New Features
- Introduced improved error snapshot formatting for validation errors, providing clearer and more structured error messages in test outputs.
-
Bug Fixes
- Enhanced error message readability by switching to a human-friendly, prettified format instead of raw JSON.
-
Chores
- Updated test configuration to use a custom snapshot serializer for consistent error representation across all tests.
- Removed deprecated function and updated example code to compare error outputs between two library versions.
Walkthrough
A custom Vitest snapshot serializer for $ZodError was introduced, and the Vitest config was updated to use it. Test snapshots throughout the codebase were updated to reflect a new, more structured and human-readable error format. The $ZodError message property now returns a prettified string instead of a JSON dump. Additionally, the example code in play.ts was simplified to directly compare error outputs from two versions of Zod.
Changes
| File(s) | Change Summary |
|---|---|
packages/zod/error-serializer.ts |
Added a new Vitest snapshot serializer for $ZodError instances, exporting an object with test and serialize methods. |
packages/zod/vitest.config.ts |
Updated Vitest config to register the new snapshot serializer for tests. |
packages/zod/src/v4/core/errors.ts |
Changed $ZodError's message getter to use a prettified, human-readable format via prettifyError instead of JSON stringifying. |
packages/zod/src/v4/classic/tests/*.test.ts |
Updated all inline test snapshots to match the new, structured error format with detailed issues arrays and prettified messages. |
play.ts |
Removed previous generic function and imports; added direct comparison of error outputs from Zod v3 and v4 for a number-string parse. |
Sequence Diagram(s)
sequenceDiagram
participant Test as Vitest Test
participant Zod as Zod Validation
participant Serializer as error-serializer.ts
Test->>Zod: Run validation (may throw $ZodError)
Zod-->>Test: Return result or throw $ZodError
Test->>Serializer: Serialize $ZodError for snapshot
Serializer-->>Test: Return formatted error string
Test-->>Test: Compare snapshot with formatted error
Possibly related PRs
- colinhacks/zod#4424: Reverted removal of
Errorinheritance fromZodErrorto fix snapshot testing breakage, closely related to error serialization and snapshot formatting. - colinhacks/zod#4074: Major migration to Zod 4 including changes to
ZodErrorclass and error formatting, directly connected to the new error serialization and snapshot updates here.
Poem
✨ A snapshot’s tale, once cryptic and terse,
Now blooms with structure, much less of a curse.
Errors are pretty, their issues laid bare,
With arrows and bullets, clarity everywhere!
So here’s to the serializer, new and refined—
May your test failures now be easier to find.
📝💥
[!NOTE]
⚡️ AI Code Reviews for VS Code, Cursor, Windsurf
CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback. Learn more here.
📜 Recent review details
Configuration used: CodeRabbit UI Review profile: ASSERTIVE Plan: Pro
📥 Commits
Reviewing files that changed from the base of the PR and between 20f94c8147b5b0c46555c991eaa13d33eb297d15 and 3da46360932757c4104a7c01dd97c7cdc20c120f.
📒 Files selected for processing (1)
packages/zod/src/v4/classic/tests/error.test.ts(12 hunks)
🔇 Additional comments (11)
packages/zod/src/v4/classic/tests/error.test.ts (11)
51-61: Snapshot reflects human‐friendly custom error map
The inline snapshot now shows the structuredissuesarray and the prettifiedmessagewith the ✖ prefix. Love the clarity here!
74-86: Updated snapshot for refinement failure with params
Theparamsblock and the consolidated ✖ message are correctly captured in the snapshot. All good!
101-113: Hard-coded override error map snapshot
The custom override message appears in both theissuesarray and the top-levelmessageas expected. LGTM!
125-134: Default error message snapshot
The default"Invalid input"message is now nicely formatted with the ✖ prefix. Looks solid.
146-155: Snapshot for string‐based refine override
The inline snapshot correctly captures the override string in bothissuesand the prettymessage. Good to go!
169-178: Snapshot for object‐style refine override
The object-style override produces the same clean ✖ message. Snapshot looks on point.
192-203: Array minimum violation snapshot
minimumandoriginfields are present and the consolidated message is correctly prefixed. Nice improvement!
212-224: Literal bigint default error snapshot
Thevaluesarray and the invalid value message are now clearly shown, with ✖ prefix. Perfect!
242-255: Custom path formatting in snapshot
The multi‐line message with the→ at items["items-too-few"]path annotation is exactly as intended.
725-735: Error serialization inline snapshot
The thrownZodErroris now serialized with the pretty message and fullissues. This matches expectations.
737-739: Inspect output snapshot
Theinspect(e)snapshot correctly showsZodError: ✖ Invalid input: expected string, received number. All set!
✨ Finishing Touches
- [ ] 📝 Generate Docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
🪧 Tips
Chat
There are 3 ways to chat with CodeRabbit:
- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
I pushed a fix in commit <commit_id>, please review it.Explain this complex logic.Open a follow-up GitHub issue for this discussion.
- Files and specific lines of code (under the "Files changed" tab): Tag
@coderabbitaiin a new review comment at the desired location with your query. Examples:@coderabbitai explain this code block.@coderabbitai modularize this function.
- PR comments: Tag
@coderabbitaiin a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.@coderabbitai read src/utils.ts and explain its main purpose.@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.@coderabbitai help me debug CodeRabbit configuration file.
Support
Need help? Create a ticket on our support page for assistance with any issues or questions.
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.
CodeRabbit Commands (Invoked using PR comments)
@coderabbitai pauseto pause the reviews on a PR.@coderabbitai resumeto resume the paused reviews.@coderabbitai reviewto trigger an incremental review. This is useful when automatic reviews are disabled for the repository.@coderabbitai full reviewto do a full review from scratch and review all the files again.@coderabbitai summaryto regenerate the summary of the PR.@coderabbitai generate docstringsto generate docstrings for this PR.@coderabbitai generate sequence diagramto generate a sequence diagram of the changes in this PR.@coderabbitai resolveresolve all the CodeRabbit review comments.@coderabbitai configurationto show the current CodeRabbit configuration for the repository.@coderabbitai helpto get help.
Other keywords and placeholders
- Add
@coderabbitai ignoreanywhere in the PR description to prevent this PR from being reviewed. - Add
@coderabbitai summaryto generate the high-level summary at a specific location in the PR description. - Add
@coderabbitaianywhere in the PR title to generate the title automatically.
CodeRabbit Configuration File (.coderabbit.yaml)
- You can programmatically configure CodeRabbit by adding a
.coderabbit.yamlfile to the root of your repository. - Please see the configuration documentation for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation:
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
Documentation and Community
- Visit our Documentation for detailed information on how to use CodeRabbit.
- Join our Discord Community to get help, request features, and share feedback.
- Follow us on X/Twitter for updates and announcements.
I'm afraid I'm avoiding this intentionally to avoid pulling prettifyError code into the bundle for Zod Mini. It's a lot of code for a small win, in my opinion. I'm not sure I like it more than the JSON.stringify version actually, since the alignment of the multi-line message gets messed up by Node's default error printer.