Skip to content

fix(effect): close type holes in catchORPCErrorCode and catchORPCErrorCodes - #2261

Merged
dinwwwh merged 3 commits into
mainfrom
claude/vibrant-babbage-vz48bm
Oct 17, 2026
Merged

dinwwwh merged 3 commits into
mainfrom
claude/vibrant-babbage-vz48bm

Conversation

@dinwwwh

@dinwwwh dinwwwh commented Oct 17, 2026

Copy link
Copy Markdown
Member

Migrates the Effect integration from @orpc/server to @orpc/client and significantly improves type inference and narrowing for error handling utilities.

Changes

  • Import migration: Updated imports from @orpc/server to @orpc/client for ORPCError and related types
  • Enhanced type inference: Introduced comprehensive type helpers (ORPCErrorsOf, ORPCErrorWithCode, ExcludeORPCErrorCode, LiteralORPCErrorCode, ORPCErrorCodeCases, etc.) to provide better type narrowing and error channel management
  • Improved catchORPCErrorCode: Now properly narrows error types based on the caught code, keeping unhandled errors in the error channel with correct type information
  • Improved catchORPCErrorCodes: Refactored type signatures to:
    • Support optional handlers (undefined values)
    • Properly track which error codes have been handled
    • Only exclude errors from the error channel when all codes in a union are handled
    • Better support for wide error types (string codes, ORPCErrorCode, etc.)
    • Preserve ORPCError subclasses with their custom properties
  • Expanded test coverage: Added comprehensive type tests for:
    • AnyORPCError handling
    • Wide error codes (string, ORPCErrorCode)
    • Union code narrowing
    • Non-literal code parameters
    • ORPCError subclasses
    • Optional/undefined handlers
    • Partial handler coverage

The changes maintain backward compatibility while providing more precise type safety for error handling workflows.

https://claude.ai/code/session_01Lg5QRphdQBu6PCo88vV51o

…rCodes

- Keep `ORPCError<any, any>` and wide-coded errors (e.g. `ORPCError<ORPCErrorCode, unknown>`,
  `ORPCError<string, unknown>`, union codes) in the result error channel, since catching one
  code does not catch the others.
- Narrow the handler error to the caught code instead of `never` for wide and union codes.
- Only exclude a member when every possible code is caught: `catchORPCErrorCode` requires a
  single literal code, and `catchORPCErrorCodes` only counts required keys whose value is a
  function, matching the runtime check.
- Merge success, error and services of handlers that may be `undefined` into the result.
- Import `ORPCError` from `@orpc/client` so client-only bundles do not pull in `@orpc/server`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lg5QRphdQBu6PCo88vV51o
- Define the "which ORPCErrors can a handler receive" rule once (`ORPCErrorsOf`)
  and reuse it in `catchORPCError` and for the code suggestions.
- Flatten `ORPCErrorWithCode` to a single inference check, and test code
  coverage with `Exclude` so `any` codes need no special-case guard.
- Reuse effect's `Types.IsUnion`, `Types.RequiredKeys`, `Types.NoExcessProperties`
  and the built-in `ReturnType` instead of hand-written equivalents.
- Share the `catchORPCErrorCodes` result type between both overloads, and use
  `AnyEffect` in the runtime signatures.

No type or runtime behavior change; per-call type instantiations drop by 16-27%.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lg5QRphdQBu6PCo88vV51o
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
orpc 14845a6 Commit Preview URL

Branch Preview URL
Oct 17 2026, 02:48 AM

@codecov

codecov Bot commented Oct 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@pkg-pr-new

pkg-pr-new Bot commented Oct 17, 2026

Copy link
Copy Markdown
More templates

@orpc/ai-sdk

npm i https://pkg.pr.new/@orpc/ai-sdk@2261

@orpc/arktype

npm i https://pkg.pr.new/@orpc/arktype@2261

@orpc/bun

npm i https://pkg.pr.new/@orpc/bun@2261

@orpc/client

npm i https://pkg.pr.new/@orpc/client@2261

@orpc/cloudflare

npm i https://pkg.pr.new/@orpc/cloudflare@2261

@orpc/contract

npm i https://pkg.pr.new/@orpc/contract@2261

@orpc/experimental-effect

npm i https://pkg.pr.new/@orpc/experimental-effect@2261

@orpc/evlog

npm i https://pkg.pr.new/@orpc/evlog@2261

@orpc/hibernation

npm i https://pkg.pr.new/@orpc/hibernation@2261

@orpc/json-schema

npm i https://pkg.pr.new/@orpc/json-schema@2261

@orpc/experimental-lock

npm i https://pkg.pr.new/@orpc/experimental-lock@2261

@orpc/experimental-msw

npm i https://pkg.pr.new/@orpc/experimental-msw@2261

@orpc/nest

npm i https://pkg.pr.new/@orpc/nest@2261

@orpc/next

npm i https://pkg.pr.new/@orpc/next@2261

@orpc/node

npm i https://pkg.pr.new/@orpc/node@2261

@orpc/openapi

npm i https://pkg.pr.new/@orpc/openapi@2261

@orpc/opentelemetry

npm i https://pkg.pr.new/@orpc/opentelemetry@2261

@orpc/pinia-colada

npm i https://pkg.pr.new/@orpc/pinia-colada@2261

@orpc/pino

npm i https://pkg.pr.new/@orpc/pino@2261

@orpc/publisher

npm i https://pkg.pr.new/@orpc/publisher@2261

@orpc/ratelimit

npm i https://pkg.pr.new/@orpc/ratelimit@2261

@orpc/server

npm i https://pkg.pr.new/@orpc/server@2261

@orpc/shared

npm i https://pkg.pr.new/@orpc/shared@2261

@orpc/swr

npm i https://pkg.pr.new/@orpc/swr@2261

@orpc/tanstack-query

npm i https://pkg.pr.new/@orpc/tanstack-query@2261

@orpc/trpc

npm i https://pkg.pr.new/@orpc/trpc@2261

@orpc/valibot

npm i https://pkg.pr.new/@orpc/valibot@2261

@orpc/zod

npm i https://pkg.pr.new/@orpc/zod@2261

commit: 14845a6

@codspeed

codspeed Bot commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

⚠️ 5 benchmarks spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

✅ 28 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing claude/vibrant-babbage-vz48bm (14845a6) with main (05f7ef3)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@dinwwwh dinwwwh changed the title refactor(effect): migrate to @orpc/client and improve type safety fix(effect): close type holes in catchORPCErrorCode and catchORPCErrorCodes Oct 17, 2026

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes — the type-level rewrite of the Effect error helpers in packages/effect/src/error.ts, the import migration to @orpc/client, and the expanded type/runtime tests. I verified the types against the runtime predicates and ran the checks below.

  • Import migration: error.ts and its tests now import ORPCError, AnyORPCError, and ORPCErrorCode from @orpc/client. @orpc/server re-exports all three from @orpc/client (packages/server/src/index.ts:26-55), so class identity and the runtime instanceof ORPCError check are unchanged, and @orpc/client is already a dependency of packages/effect.
  • Extracted type helpers: ORPCErrorsOf, ORPCErrorCodeOf, ORPCErrorWithCode, ExcludeORPCErrorCode, LiteralORPCErrorCode, ORPCErrorCodeCases, HandledORPCErrorCodes, ORPCErrorCodeCasesEffect, and CatchORPCErrorCodesEffect replace the previous inline conditionals.
  • catchORPCErrorCode narrowing: the error channel drops a member only when the caught code is a single literal (LiteralORPCErrorCode returns never for unions, string, and ORPCErrorCode) and that member's whole code union is contained in it; wide/union codes, ORPCError<string>, ORPCError<ORPCErrorCode>, AnyORPCError, and hidden-Error channels all keep the error in the channel.
  • catchORPCErrorCodes handling: only required keys with a function value enter HandledORPCErrorCodes — undefined and optional handlers keep their code in the error channel, which fixes prior unsoundness where keyof Cases excluded those codes even though the getOwn runtime predicate skips them.
  • Test coverage: added type tests for wide codes, union narrowing, ORPCError subclasses, AnyORPCError, undeclared keys on hidden channels, and optional/undefined handlers, plus the runtime import update.

Verification: tsc -b packages/effect --force, root tsc --noEmit -p tsconfig.json (covers *.test-d.ts), vitest run packages/effect/src/error.test.ts (20/20), and eslint on the three changed files all pass.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@dinwwwh
dinwwwh merged commit 55947af into main Oct 17, 2026
12 checks passed
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.

2 participants