zod icon indicating copy to clipboard operation
zod copied to clipboard

Human friendly error messages

Open RobinTail opened this issue 7 months ago • 1 comments

In v4 I suggest to make ZodError::message more readable and human friendly by utilizing the already implemented prettifyError() in its getter.

image

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.

RobinTail avatar May 20 '25 04:05 RobinTail

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 Error inheritance from ZodError to fix snapshot testing breakage, closely related to error serialization and snapshot formatting.
  • colinhacks/zod#4074: Major migration to Zod 4 including changes to ZodError class 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 structured issues array and the prettified message with the ✖ prefix. Love the clarity here!


74-86: Updated snapshot for refinement failure with params
The params block 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 the issues array and the top-level message as 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 both issues and the pretty message. 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
minimum and origin fields are present and the consolidated message is correctly prefixed. Nice improvement!


212-224: Literal bigint default error snapshot
The values array 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 thrown ZodError is now serialized with the pretty message and full issues. This matches expectations.


737-739: Inspect output snapshot
The inspect(e) snapshot correctly shows ZodError: ✖ 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.

❤️ Share
🪧 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 @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in 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 pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file 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.

coderabbitai[bot] avatar May 20 '25 04:05 coderabbitai[bot]

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.

Screenshot 2025-05-27 at 19 14 27

colinhacks avatar May 28 '25 02:05 colinhacks