Skip to content

Conversation

@luxass
Copy link
Member

@luxass luxass commented Jan 5, 2026

🔗 Linked issue

📚 Description

This PR adds a custom error for when schema fails validation.

This will help close the mega PR of #420

Summary by CodeRabbit

  • New Features

    • Introduced specialized error handling for data validation failures with detailed error information including validation issues.
    • Schema validation now restricted to successful responses only.
  • Improvements

    • Enhanced error propagation to preserve and maintain error details throughout the fetch process.

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings January 5, 2026 05:54
@changeset-bot
Copy link

changeset-bot bot commented Jan 5, 2026

⚠️ No Changeset found

Latest commit: 2ac5d5d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 5, 2026

Warning

Rate limit exceeded

@luxass has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 22 minutes and 52 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 86d2939 and 2ac5d5d.

📒 Files selected for processing (4)
  • packages/shared/src/fetch/error.ts
  • packages/shared/src/fetch/fetch.ts
  • packages/shared/src/fetch/types.ts
  • packages/shared/test/fetch/fetch-schema.test.ts

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

This PR introduces a specialized FetchSchemaValidationError class for handling response schema validation failures, updates fetch logic to use this error type and gate validation to successful responses only, and updates the response type to reflect the new error variant.

Changes

Cohort / File(s) Summary
New error type
packages/shared/src/fetch/error.ts
Introduced FetchSchemaValidationError<T> extending FetchError<T> with optional issues property and dedicated constructor for schema-specific errors
Fetch implementation
packages/shared/src/fetch/fetch.ts
Updated error handling to preserve and propagate FetchError subclasses; added dedicated FetchSchemaValidationError for schema validation failures; gated schema validation to successful responses only (status < 400)
Type updates
packages/shared/src/fetch/types.ts
Updated SafeFetchResponse.error type to include FetchSchemaValidationError<T> alongside FetchError<T>
Tests
packages/shared/test/fetch/fetch-schema.test.ts
Updated test expectations to use FetchSchemaValidationError for schema validation failures; added test coverage for error responses (400, 500) and validated error cause/issues properties

Sequence Diagram

sequenceDiagram
    participant Client
    participant Fetch Handler
    participant Schema Validator
    participant Error Handler
    participant Response

    Client->>Fetch Handler: fetch with schema
    Fetch Handler->>Response: HTTP request
    Response->>Fetch Handler: response received
    
    alt Status < 400 (Success)
        Fetch Handler->>Schema Validator: validate response against schema
        alt Validation passes
            Fetch Handler->>Client: return typed response
        else Validation fails
            rect rgb(255, 200, 200)
                Schema Validator->>Error Handler: throw ValidationError
                Error Handler->>Error Handler: wrap in FetchSchemaValidationError
                Error Handler-->>Error Handler: attach cause & issues
            end
            Error Handler->>Client: throw FetchSchemaValidationError
        end
    else Status >= 400 (Error)
        rect rgb(200, 200, 255)
            Fetch Handler->>Error Handler: skip schema validation
            Error Handler->>Client: throw FetchError
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • feat(shared): add custom fetch #316: Directly extends the fetch error model by modifying the same fetch/error.ts, fetch.ts, and types.ts modules to introduce specialized schema validation error handling alongside base FetchError.

Suggested labels

pkg: shared

Poem

🐰 A schema's dance, validation born,
Where errors now have their own form,
FetchSchemaValidationError hops in place,
With issues tracked and causes traced,
Safe responses, properly guarded with grace!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title accurately describes the main change: introducing a new FetchSchemaValidationError class and custom error handling specifically for schema validation failures, which aligns with the core changes across all modified files.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the pkg: shared Changes related to the Shared package. label Jan 5, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 5, 2026

🌏 Preview Deployments

Application Status Preview URL
API ✅ Deployed View Preview
Website ✅ Deployed View Preview

Built from commit: 2ac5d5d962cdf8c39d892faa1dfb30495987ff66


🤖 This comment will be updated automatically when you push new commits to this PR.

@codecov
Copy link

codecov bot commented Jan 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds custom error handling for schema validation failures by introducing a new FetchSchemaValidationError class that extends FetchError. The changes enable more specific error handling when response data fails Zod schema validation.

Key Changes

  • Introduced FetchSchemaValidationError class with an issues field to capture Zod validation errors
  • Updated schema validation logic to use the new error type and preserve it through the error handling flow
  • Added tests covering schema validation failures for both successful and error responses

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
packages/shared/src/fetch/error.ts Adds new FetchSchemaValidationError class extending FetchError with validation issues support
packages/shared/src/fetch/fetch.ts Updates error handling to preserve FetchError subclasses and uses FetchSchemaValidationError for schema validation failures
packages/shared/src/fetch/types.ts Updates SafeFetchResponse type to include FetchSchemaValidationError in error union type
packages/shared/test/fetch/fetch-schema.test.ts Adds comprehensive test coverage for the new error handling behavior including edge cases with error responses

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@greptile-apps
Copy link

greptile-apps bot commented Jan 5, 2026

Greptile Summary

This PR introduces dedicated error handling for schema validation failures in the custom fetch utility. A new FetchSchemaValidationError class extends FetchError to distinguish schema validation failures from other fetch errors, providing access to Zod validation issues for better debugging.

Key Changes:

  • Added FetchSchemaValidationError class with issues field for Zod error details
  • Enhanced error preservation logic to maintain FetchSchemaValidationError instances through the error handler
  • Schema validation now only runs on successful responses (status < 400), preventing validation errors from masking actual HTTP errors
  • Updated type definitions to reflect the new error type in SafeFetchResponse
  • Added comprehensive tests for error response scenarios

Issue Found:

  • Test file contains invalid Zod syntax: z.email() should be z.string().email() on line 12

Confidence Score: 4/5

  • This PR is safe to merge with one syntax fix required
  • The implementation is well-designed with proper error subclassing and comprehensive test coverage. The logic correctly preserves error instances and only validates successful responses. However, the test file contains a syntax error (z.email() instead of z.string().email()) that will cause test failures. Once fixed, this is a solid enhancement to error handling.
  • Fix the Zod syntax error in packages/shared/test/fetch/fetch-schema.test.ts:12 before merging

Important Files Changed

Filename Overview
packages/shared/src/fetch/error.ts Added FetchSchemaValidationError class extending FetchError with issues field for Zod validation errors
packages/shared/src/fetch/fetch.ts Enhanced error handling to preserve FetchSchemaValidationError instances; added status check to skip validation for error responses (status >= 400)
packages/shared/test/fetch/fetch-schema.test.ts Updated tests to verify FetchSchemaValidationError and added edge case tests for error responses; contains invalid Zod syntax on line 12

Sequence Diagram

sequenceDiagram
    participant Client
    participant customFetch
    participant fetch API
    participant Schema
    participant ErrorHandler

    Client->>customFetch: customFetch(url, {schema})
    customFetch->>fetch API: fetch(request, options)
    
    alt Fetch Success
        fetch API-->>customFetch: Response
        
        alt Status < 400 (Success)
            customFetch->>customFetch: Parse response data
            customFetch->>Schema: schema.safeParseAsync(data)
            
            alt Validation Success
                Schema-->>customFetch: {success: true, data}
                customFetch-->>Client: FetchResponse with validated data
            else Validation Failed
                Schema-->>customFetch: {success: false, error}
                customFetch->>ErrorHandler: FetchSchemaValidationError
                ErrorHandler-->>Client: Throw FetchSchemaValidationError
            end
        else Status >= 400 (Error)
            Note over customFetch,Schema: Skip schema validation
            customFetch->>ErrorHandler: FetchError
            ErrorHandler-->>Client: Throw FetchError
        end
    else Fetch Failed
        fetch API-->>customFetch: Error
        customFetch->>ErrorHandler: handleError()
        ErrorHandler-->>Client: Throw FetchError
    end
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Fix all issues with AI Agents 🤖
In @packages/shared/test/fetch/fetch-schema.test.ts:
- Around line 164-173: The test name "should emit FetchSchemaValidationError
when error response fails schema" contradicts its assertions which check for
FetchError and not FetchSchemaValidationError; update the test description (the
it(...) string) to accurately reflect actual behavior—for example "should return
FetchError and not FetchSchemaValidationError for error-invalid response"—so the
test name matches the assertions involving FetchError and
FetchSchemaValidationError in the test block.
🧹 Nitpick comments (1)
packages/shared/src/fetch/error.ts (1)

63-75: Consider making cause optional in the constructor options.

The parent class FetchError has opts?: { cause: unknown } where cause is effectively required when opts is provided. However, the new FetchSchemaValidationError constructor signature opts?: { cause: unknown; issues?: unknown } requires cause to be present if opts is passed, which prevents passing only issues without a cause.

For consistency and flexibility, consider making cause optional:

🔎 Proposed fix
-  constructor(message: string, opts?: { cause: unknown; issues?: unknown }) {
+  constructor(message: string, opts?: { cause?: unknown; issues?: unknown }) {
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b06a7dd and 86d2939.

📒 Files selected for processing (4)
  • packages/shared/src/fetch/error.ts
  • packages/shared/src/fetch/fetch.ts
  • packages/shared/src/fetch/types.ts
  • packages/shared/test/fetch/fetch-schema.test.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{test,spec}.?(c|m)[jt]s?(x)

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{test,spec}.?(c|m)[jt]s?(x): Import test utilities from #test-utils/* path aliases instead of @ucdjs/test-utils in test files to avoid build step requirements and prevent cyclic dependencies
Use testdir() from vitest-testdirs to create temporary test directories in filesystem tests
Use mockStoreApi() utility from #test-utils/mock-store for MSW-based mocking of the UCD API in test files

Files:

  • packages/shared/test/fetch/fetch-schema.test.ts
🧠 Learnings (1)
📚 Learning: 2025-12-27T11:08:54.630Z
Learnt from: CR
Repo: ucdjs/ucd PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-27T11:08:54.630Z
Learning: Applies to apps/api/src/**/*.ts : Use Zod schemas for defining API route schemas and request/response types in the API application

Applied to files:

  • packages/shared/src/fetch/types.ts
🧬 Code graph analysis (2)
packages/shared/src/fetch/types.ts (1)
packages/shared/src/fetch/error.ts (2)
  • FetchError (8-62)
  • FetchSchemaValidationError (64-75)
packages/shared/src/fetch/fetch.ts (1)
packages/shared/src/fetch/error.ts (2)
  • FetchError (8-62)
  • FetchSchemaValidationError (64-75)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Upload results
  • GitHub Check: lint
  • GitHub Check: typecheck
  • GitHub Check: Greptile Review
  • GitHub Check: test (windows-latest)
  • GitHub Check: test (macos-latest)
🔇 Additional comments (7)
packages/shared/src/fetch/types.ts (1)

2-2: LGTM!

The type updates correctly expand SafeFetchResponse.error to include the new FetchSchemaValidationError<T> variant, maintaining proper type parameter propagation. This aligns well with the runtime changes in fetch.ts.

Also applies to: 29-33

packages/shared/src/fetch/fetch.ts (3)

85-100: LGTM! Good preservation of error subclass identity.

The updated handleError correctly preserves FetchError subclasses (like FetchSchemaValidationError) while ensuring common fields are attached. This maintains the error type through the retry/error handling flow.


222-226: Verify this design choice aligns with expected usage patterns.

Schema validation is now skipped for error responses (status >= 400). This means users cannot validate error response payloads against a schema—they'll receive a generic FetchError instead of FetchSchemaValidationError.

If this is intentional (e.g., schemas are meant only for success responses), consider documenting this behavior in the schema option's JSDoc at lines 45-53.


229-233: LGTM!

The FetchSchemaValidationError is constructed with appropriate context: a descriptive message, the original Zod error as the cause, and the validation issues for programmatic inspection.

packages/shared/test/fetch/fetch-schema.test.ts (3)

1-6: LGTM!

The test imports correctly bring in the new FetchSchemaValidationError alongside FetchError for assertion purposes. The import path to production code is appropriate here (the coding guidelines about #test-utils/* apply to test utilities, not production exports).


136-162: Good coverage of error response scenarios.

These tests effectively validate that schema validation is skipped for error responses (status >= 400), ensuring users receive FetchError rather than FetchSchemaValidationError for 4xx/5xx responses.


12-12: No action needed. z.email() is the correct syntax for Zod 4.2.1 (the version used by this project). This is a top-level string format factory introduced in Zod 4.x and is the standard way to validate email format.

luxass added 3 commits January 5, 2026 17:14
Introduce `FetchSchemaValidationError` to handle schema validation errors specifically. Update `createCustomFetch` to throw this error when response validation fails, preserving context and issues for better debugging. Update type definitions to accommodate the new error type.
- Introduced `FetchSchemaValidationError` for better error categorization.
- Added tests for various error response scenarios to ensure robust validation.
- Updated existing tests to reflect changes in error handling logic.
@luxass luxass force-pushed the feat/custom-error-for-fetch-schema branch from efda26e to 2ac5d5d Compare January 5, 2026 16:14
@luxass luxass merged commit 95b6ba7 into main Jan 5, 2026
23 checks passed
@luxass luxass deleted the feat/custom-error-for-fetch-schema branch January 5, 2026 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg: shared Changes related to the Shared package.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants