Skip to content

Conversation

@AlexandrHoroshih
Copy link
Member

@AlexandrHoroshih AlexandrHoroshih commented Dec 25, 2025

This PR introduces a new mapError configuration option for Queries, allowing transformation of error data before it reaches .finished.failure and .$error.

Features

  • mapError for createQuery and createMutation - Transform errors from effects with optional source store support
  • mapError for createJsonQuery and createJsonMutation - Transform HTTP/network/contract errors with access to response headers
  • Headers access - For HTTP errors (4xx/5xx) and contract/validation errors, raw response headers are available in the mapper. Network errors don't have headers (no response received).

API

// Simple function
createJsonQuery({
  request: { method: 'GET', url: '/api/users' },
  response: {
    contract: userContract,
    mapError: ({ error, params, headers }) => ({
      message: isHttpError({ error }) ? `HTTP ${error.status}` : 'Network error',
      requestId: headers?.get('X-Request-Id'),
    }),
  },
});

// With source store
createJsonQuery({
  request: { method: 'GET', url: '/api/users' },
  response: {
    contract: userContract,
    mapError: {
      source: $errorMessages,
      fn: ({ error, headers }, messages) => ({
        message: messages[error.status] ?? 'Unknown error',
      }),
    },
  },
});

Implementation Details

  • Modified requestFx to throw structured errors { error, responseMeta?: { headers } }
  • Propagated responseMeta through the entire error flow (requestFxapiRequestFxcreateRemoteOperation)
  • Added failedBeforeMap intermediate event to apply mapError before errors reach public API
  • HttpError remains safely serializable (headers are passed separately, not stored in the error object)

Breaking Changes

None - mapError is optional and all existing behavior is preserved.

Copy link

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 implements a new mapFailure configuration option for Queries, enabling transformation of error data before it reaches the public API (.$error store and .finished.failure event). The implementation modifies the error flow to include response headers in a responseMeta structure, which is propagated through all error paths and made available to the mapFailure mapper alongside the error object and query parameters.

Key Changes:

  • Added mapFailure mapper support to createQuery and createJsonQuery with optional source store capability
  • Modified error structure throughout the fetch layer to include responseMeta containing response headers
  • Introduced failedBeforeMap intermediate event to apply error transformation before errors reach public API

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/core/src/fetch/request.ts Modified requestFx to throw structured errors containing both error and optional responseMeta with headers
packages/core/src/fetch/api.ts Updated apiRequestFx to preserve responseMeta through error transformation and propagate headers for preparation and validation errors
packages/core/src/remote_operation/create_remote_operation.ts Implemented core mapFailure logic with new failedBeforeMap event, default identity mapper, and responseMeta propagation through all failure paths
packages/core/src/query/create_query.ts Integrated mapFailure parameter into createQuery's remote operation initialization
packages/core/src/query/create_json_query.ts Added mapFailure type signatures across all createJsonQuery overloads and passed it to remote operation
packages/core/src/query/create_headless_query.ts Added MappedError and MapFailureSource type parameters with mapFailure configuration support
packages/core/src/mutation/create_headless_mutation.ts Updated type parameters to include placeholders for MappedError and MapFailureSource (mutations don't support mapFailure yet)
packages/core/src/query/__tests__/create_json_query.response.map_failure.test.ts Comprehensive test coverage for mapFailure with simple/sourced callbacks, params access, and headers availability for different error types
packages/core/src/fetch/__tests__/request.test.ts Updated expectations to reflect new error structure with responseMeta
packages/core/src/fetch/__tests__/json.response.data.test.ts Updated test assertions for preparation errors to include responseMeta
packages/core/src/fetch/__tests__/json.failed.data.test.ts Updated test expectations for HTTP errors to include responseMeta
packages/core/src/fetch/__tests__/api.response.extract.test.ts Updated preparation error test assertions
packages/core/src/fetch/__tests__/api.response.all_in_one.test.ts Updated test expectations for error structure
packages/core/src/retry/__tests__/retry.query.test.ts Added responseMeta: undefined to test snapshot
packages/core/src/remote_operation/__test__/create_remote_operation.test.ts Added responseMeta: undefined to test snapshots
packages/core/src/concurrency/__tests__/concurrency.test.ts Added responseMeta: undefined to test snapshot
apps/website/docs/recipes/data_flow.md Added comprehensive documentation for error mapping stage with sourced example and headers explanation
apps/website/docs/api/factories/create_query.md Documented mapFailure API for both simple function and sourced variants
apps/website/docs/api/factories/create_json_query.md Added mapFailure documentation with error types and headers availability details
packages/core/package.json Updated size limit from 16 kB to 16.17 kB to accommodate new feature
.changeset/popular-panthers-hope.md Added changeset entry marking this as a minor release

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

AlexandrHoroshih and others added 2 commits December 25, 2025 19:13
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Member

@igorkamyshev igorkamyshev left a comment

Choose a reason for hiding this comment

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

LGTM, some questions were asked in committee chat.

@AlexandrHoroshih AlexandrHoroshih changed the title Implement mapFailure Implement mapError Dec 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants