From 7ec7357356c67a3e5536ad722d555fab338141d2 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 16 Oct 2026 13:45:31 +0000 Subject: [PATCH 1/3] fix(effect): close type holes in catchORPCErrorCode and catchORPCErrorCodes - Keep `ORPCError` and wide-coded errors (e.g. `ORPCError`, `ORPCError`, 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 Claude-Session: https://claude.ai/code/session_01Lg5QRphdQBu6PCo88vV51o --- packages/effect/src/error.test-d.ts | 182 +++++++++++++++++++++++++++- packages/effect/src/error.test.ts | 2 +- packages/effect/src/error.ts | 113 +++++++++++------ 3 files changed, 257 insertions(+), 40 deletions(-) diff --git a/packages/effect/src/error.test-d.ts b/packages/effect/src/error.test-d.ts index 65cd32dce7..05c96d8680 100644 --- a/packages/effect/src/error.test-d.ts +++ b/packages/effect/src/error.test-d.ts @@ -1,4 +1,5 @@ -import type { ORPCError, ORPCErrorCode } from '@orpc/server' +import type { AnyORPCError, ORPCErrorCode } from '@orpc/client' +import { ORPCError } from '@orpc/client' import { Effect } from 'effect' import { catchORPCError, catchORPCErrorCode, catchORPCErrorCodes } from './error' @@ -22,6 +23,14 @@ const effectWithHidden = {} as Effect.Effect< Service1 > +const effectWithAny = Effect.fail(new Error('boom') as unknown).pipe( + Effect.mapError(error => error instanceof ORPCError ? error : new ORPCError('INTERNAL_SERVER_ERROR')), +) + +const effectWithWide = {} as Effect.Effect<'output', ORPCError> +const effectWithString = {} as Effect.Effect<'output', ORPCError> +const effectWithUnion = {} as Effect.Effect<'output', ORPCError<'NOT_FOUND' | 'CONFLICT', { id: string }>> + describe('catchORPCError', () => { it('catches every ORPCError and excludes them from the error channel (data-last)', () => { const recovered = effect.pipe(catchORPCError((error) => { @@ -180,6 +189,81 @@ describe('catchORPCErrorCode', () => { // @ts-expect-error - BAD_GATEWAY is not present and the channel cannot hold hidden ORPCErrors void withString.pipe(catchORPCErrorCode('BAD_GATEWAY', () => Effect.succeed('recovered'))) }) + + it('keeps AnyORPCError in the error channel and narrows the handler to the caught code', () => { + expectTypeOf(effectWithAny).toEqualTypeOf>() + + const recovered = effectWithAny.pipe(catchORPCErrorCode('NOT_FOUND', (error) => { + expectTypeOf(error).toEqualTypeOf>() + return Effect.succeed(error.code) + })) + + expectTypeOf(recovered).toEqualTypeOf>() + }) + + it('narrows wide codes to the caught code and keeps them in the error channel', () => { + const recoveredWide = effectWithWide.pipe(catchORPCErrorCode('NOT_FOUND', (error) => { + expectTypeOf(error).toEqualTypeOf>() + return Effect.succeed(error.code) + })) + + expectTypeOf(recoveredWide).toEqualTypeOf>>() + + const recoveredString = catchORPCErrorCode(effectWithString, 'NOT_FOUND', (error) => { + expectTypeOf(error).toEqualTypeOf>() + return Effect.succeed(error.code) + }) + + expectTypeOf(recoveredString).toEqualTypeOf>>() + }) + + it('narrows union codes to the caught code and keeps them in the error channel', () => { + const recovered = effectWithUnion.pipe(catchORPCErrorCode('NOT_FOUND', (error) => { + expectTypeOf(error).toEqualTypeOf>() + return Effect.succeed(error.data.id) + })) + + expectTypeOf(recovered).toEqualTypeOf< + Effect.Effect<'output' | string, ORPCError<'NOT_FOUND' | 'CONFLICT', { id: string }>> + >() + }) + + it('keeps errors in the error channel when the code is not a single literal', () => { + const code = {} as 'NOT_FOUND' | 'CONFLICT' + + const recoveredUnion = effect.pipe(catchORPCErrorCode(code, (error) => { + expectTypeOf(error).toEqualTypeOf | ORPCError<'CONFLICT', number>>() + return Effect.succeed('recovered' as const) + })) + + expectTypeOf(recoveredUnion).toEqualTypeOf< + Effect.Effect<'output' | 'recovered', ORPCError<'NOT_FOUND', { id: string }> | ORPCError<'CONFLICT', number>, Service1> + >() + + const recoveredString = effectWithHidden.pipe(catchORPCErrorCode({} as string, (error) => { + expectTypeOf(error).toEqualTypeOf | ORPCError>() + return Effect.succeed('recovered' as const) + })) + + expectTypeOf(recoveredString).toEqualTypeOf< + Effect.Effect<'output' | 'recovered', ORPCError<'NOT_FOUND', { id: string }> | Error, Service1> + >() + }) + + it('keeps ORPCError subclasses', () => { + class NotFoundError extends ORPCError<'NOT_FOUND', { id: string }> { + declare readonly extra: 'extra' + } + + const withSubclass = {} as Effect.Effect<'output', NotFoundError | ORPCError<'CONFLICT', number>> + + const recovered = withSubclass.pipe(catchORPCErrorCode('NOT_FOUND', (error) => { + expectTypeOf(error).toEqualTypeOf() + return Effect.succeed(error.extra) + })) + + expectTypeOf(recovered).toEqualTypeOf>>() + }) }) describe('catchORPCErrorCodes', () => { @@ -246,4 +330,100 @@ describe('catchORPCErrorCodes', () => { // @ts-expect-error - BAD_GATEWAY is not present and the channel cannot hold hidden ORPCErrors void withString.pipe(catchORPCErrorCodes({ BAD_GATEWAY: () => Effect.succeed('recovered') })) }) + + it('keeps AnyORPCError in the error channel', () => { + const recovered = effectWithAny.pipe(catchORPCErrorCodes({ + NOT_FOUND: (error) => { + expectTypeOf(error).toEqualTypeOf() + return Effect.succeed('nf' as const) + }, + })) + + expectTypeOf(recovered).toEqualTypeOf>() + }) + + it('types handlers of wide codes and keeps them in the error channel', () => { + const recoveredWide = effectWithWide.pipe(catchORPCErrorCodes({ + NOT_FOUND: (error) => { + expectTypeOf(error).toEqualTypeOf>() + return Effect.succeed('nf' as const) + }, + })) + + expectTypeOf(recoveredWide).toEqualTypeOf>>() + + const recoveredString = catchORPCErrorCodes(effectWithString, { + NOT_FOUND: (error) => { + expectTypeOf(error).toEqualTypeOf>() + return Effect.succeed('nf' as const) + }, + }) + + expectTypeOf(recoveredString).toEqualTypeOf>>() + }) + + it('types handlers of undeclared keys when the channel can hold hidden ORPCErrors', () => { + void effectWithHidden.pipe(catchORPCErrorCodes({ + __CUSTOM__: (error) => { + expectTypeOf(error).toExtend() + expectTypeOf(error.code).toExtend() + expectTypeOf(error.data).toEqualTypeOf() + return Effect.succeed('recovered' as const) + }, + })) + }) + + it('narrows union codes and excludes them only once every code is handled', () => { + const recoveredOne = effectWithUnion.pipe(catchORPCErrorCodes({ + NOT_FOUND: (error) => { + expectTypeOf(error).toEqualTypeOf>() + return Effect.succeed('nf' as const) + }, + })) + + expectTypeOf(recoveredOne).toEqualTypeOf< + Effect.Effect<'output' | 'nf', ORPCError<'NOT_FOUND' | 'CONFLICT', { id: string }>> + >() + + const recoveredAll = effectWithUnion.pipe(catchORPCErrorCodes({ + NOT_FOUND: () => Effect.succeed('nf' as const), + CONFLICT: (error) => { + expectTypeOf(error).toEqualTypeOf>() + return Effect.succeed('cf' as const) + }, + })) + + expectTypeOf(recoveredAll).toEqualTypeOf>() + }) + + it('keeps codes whose handler can be undefined in the error channel', () => { + const recoveredUndefined = effect.pipe(catchORPCErrorCodes({ + NOT_FOUND: undefined, + CONFLICT: () => Effect.succeed('cf' as const), + })) + + expectTypeOf(recoveredUndefined).toEqualTypeOf< + Effect.Effect<'output' | 'cf', ORPCError<'NOT_FOUND', { id: string }>, Service1> + >() + + const maybeHandler = {} as ((error: ORPCError<'NOT_FOUND', { id: string }>) => Effect.Effect<'nf', RangeError, Service2>) | undefined + + const recoveredMaybe = effect.pipe(catchORPCErrorCodes({ NOT_FOUND: maybeHandler })) + + expectTypeOf(recoveredMaybe).toEqualTypeOf< + Effect.Effect< + 'output' | 'nf', + ORPCError<'NOT_FOUND', { id: string }> | ORPCError<'CONFLICT', number> | RangeError, + Service1 | Service2 + > + >() + + const optionalCases = {} as { NOT_FOUND?: (error: ORPCError<'NOT_FOUND', { id: string }>) => Effect.Effect<'nf'> } + + const recoveredOptional = effect.pipe(catchORPCErrorCodes(optionalCases)) + + expectTypeOf(recoveredOptional).toEqualTypeOf< + Effect.Effect<'output' | 'nf', ORPCError<'NOT_FOUND', { id: string }> | ORPCError<'CONFLICT', number>, Service1> + >() + }) }) diff --git a/packages/effect/src/error.test.ts b/packages/effect/src/error.test.ts index fe6addf3bf..8b3f6ea415 100644 --- a/packages/effect/src/error.test.ts +++ b/packages/effect/src/error.test.ts @@ -1,4 +1,4 @@ -import { ORPCError } from '@orpc/server' +import { ORPCError } from '@orpc/client' import { Cause, Effect, Exit } from 'effect' import { catchORPCError, catchORPCErrorCode, catchORPCErrorCodes } from './error' diff --git a/packages/effect/src/error.ts b/packages/effect/src/error.ts index 320c49a28b..e9805ba815 100644 --- a/packages/effect/src/error.ts +++ b/packages/effect/src/error.ts @@ -1,8 +1,67 @@ -import type { AnyORPCError, ORPCErrorCode } from '@orpc/server' -import { ORPCError } from '@orpc/server' +import type { AnyORPCError, ORPCErrorCode } from '@orpc/client' +import { ORPCError } from '@orpc/client' import { getOwn } from '@orpc/shared' import { Effect, Function } from 'effect' +type AnyEffect = Effect.Effect + +/** + * Codes an `ORPCError` in `E` can have. Any code is possible when `E` + * can hold hidden `ORPCError` instances. + */ +type ORPCErrorCodeOf = E extends ORPCError ? TCode : AnyORPCError extends E ? ORPCErrorCode : never + +/** + * The `ORPCError`s in `E` whose code can be `TCode`, narrowed to `TCode`. + * Hidden `ORPCError` instances have unknown data. + */ +type ORPCErrorWithCode = E extends AnyORPCError + ? E extends ORPCError + ? 0 extends (1 & UCode) + ? ORPCError + : [UCode] extends [TCode] + ? E + : [UCode & TCode] extends [never] ? never : ORPCError + : never + : AnyORPCError extends E ? ORPCError : never + +/** + * `E` without the `ORPCError`s whose every possible code is in `TCode`. + */ +type ExcludeORPCErrorCode = E extends ORPCError + ? 0 extends (1 & UCode) ? E : [UCode] extends [TCode] ? never : E + : E + +/** + * `TCode` if it is a single literal code, `never` otherwise. + */ +type LiteralORPCErrorCode = UCode extends string + ? [TCode] extends [UCode] ? Record extends Record ? never : UCode : never + : never + +/** + * The codes `TCases` handles: required, literal keys with a function value. + */ +type HandledORPCErrorCodes = { + [K in keyof TCases]-?: Record extends Pick ? never : TCases[K] extends (...args: any[]) => any ? K : never +}[keyof TCases] & string + +/** + * The handlers `catchORPCErrorCodes` accepts, keyed by the codes in `E`. + * Non-literal codes (e.g. hidden `ORPCError` instances) become an index + * signature, whose handler is bivariant so it accepts every literal handler. + */ +type ORPCErrorCodeCases = { + [K in ORPCErrorCodeOf]?: Record extends Record + ? { bivarianceHack(error: ORPCErrorWithCode): AnyEffect }['bivarianceHack'] + : (error: ORPCErrorWithCode) => AnyEffect +} + +/** + * The effects the handlers in `TCases` can return. + */ +type ORPCErrorCodeCasesEffect = TCase extends (...args: any[]) => infer U ? U : never + /** * Recovers from `ORPCError` failures in the error channel of an effect. * Other failures re-fail with their original cause. Because failure types @@ -66,15 +125,15 @@ export const catchORPCError: { * @see {@link https://orpc.dev/docs/integrations/effect#catching-orpcerrors | Effect Integration - Catching ORPCErrors} */ export const catchORPCErrorCode: { - ? TCode : AnyORPCError extends E ? ORPCErrorCode : never, E, A2, E2, R2>( + , E, A2, E2, R2>( code: TCode, - f: (error: E extends AnyORPCError ? Extract> : AnyORPCError extends E ? ORPCError : never) => Effect.Effect, - ): (self: Effect.Effect) => Effect.Effect>, R | R2> - ? TCode : AnyORPCError extends E ? ORPCErrorCode : never, A2, E2, R2>( + f: (error: ORPCErrorWithCode) => Effect.Effect, + ): (self: Effect.Effect) => Effect.Effect>, R | R2> + , A2, E2, R2>( self: Effect.Effect, code: TCode, - f: (error: E extends AnyORPCError ? Extract> : AnyORPCError extends E ? ORPCError : never) => Effect.Effect, - ): Effect.Effect>, R | R2> + f: (error: ORPCErrorWithCode) => Effect.Effect, + ): Effect.Effect>, R | R2> } = Function.dual( 3, ( @@ -114,42 +173,20 @@ export const catchORPCErrorCode: { * @see {@link https://orpc.dev/docs/integrations/effect#catching-orpcerrors | Effect Integration - Catching ORPCErrors} */ export const catchORPCErrorCodes: { - < - E, - Cases extends - & { [K in E extends ORPCError ? TCode : AnyORPCError extends E ? ORPCErrorCode : never]?: string extends K - ? (error: never) => Effect.Effect - : K extends infer C extends ORPCErrorCode - ? (error: E extends AnyORPCError ? Extract> : AnyORPCError extends E ? ORPCError : never) => Effect.Effect - : never } - & { [K in Exclude ? TCode : AnyORPCError extends E ? ORPCErrorCode : never>]: never }, - >( + & { [K in Exclude>]: never }>( cases: Cases, ): (self: Effect.Effect) => Effect.Effect< - A | { [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect ? A2 : never }[keyof Cases], - | Exclude> - | { [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect ? E2 : never }[keyof Cases], - R | { [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect ? R2 : never }[keyof Cases] + A | Effect.Success>, + ExcludeORPCErrorCode> | Effect.Error>, + R | Effect.Services> > - < - A, - E, - R, - Cases extends - & { [K in E extends ORPCError ? TCode : AnyORPCError extends E ? ORPCErrorCode : never]?: string extends K - ? (error: never) => Effect.Effect - : K extends infer C extends ORPCErrorCode - ? (error: E extends AnyORPCError ? Extract> : AnyORPCError extends E ? ORPCError : never) => Effect.Effect - : never } - & { [K in Exclude ? TCode : AnyORPCError extends E ? ORPCErrorCode : never>]: never }, - >( + & { [K in Exclude>]: never }>( self: Effect.Effect, cases: Cases, ): Effect.Effect< - A | { [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect ? A2 : never }[keyof Cases], - | Exclude> - | { [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect ? E2 : never }[keyof Cases], - R | { [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect ? R2 : never }[keyof Cases] + A | Effect.Success>, + ExcludeORPCErrorCode> | Effect.Error>, + R | Effect.Services> > } = Function.dual( 2, From 12ac20c8bf77b301c23d91bf5dcec9fedeb654d0 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 17 Oct 2026 02:26:29 +0000 Subject: [PATCH 2/3] refactor(effect): simplify catchORPCErrorCode(s) type helpers - 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 Claude-Session: https://claude.ai/code/session_01Lg5QRphdQBu6PCo88vV51o --- packages/effect/src/error.ts | 97 +++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/packages/effect/src/error.ts b/packages/effect/src/error.ts index e9805ba815..bbc8de12fb 100644 --- a/packages/effect/src/error.ts +++ b/packages/effect/src/error.ts @@ -1,4 +1,5 @@ import type { AnyORPCError, ORPCErrorCode } from '@orpc/client' +import type { Types } from 'effect' import { ORPCError } from '@orpc/client' import { getOwn } from '@orpc/shared' import { Effect, Function } from 'effect' @@ -6,61 +7,71 @@ import { Effect, Function } from 'effect' type AnyEffect = Effect.Effect /** - * Codes an `ORPCError` in `E` can have. Any code is possible when `E` - * can hold hidden `ORPCError` instances. + * The `ORPCError`s a handler can receive from `E`. Failure types like `Error` + * can also hold hidden `ORPCError` instances, whose code and data are unknown. */ -type ORPCErrorCodeOf = E extends ORPCError ? TCode : AnyORPCError extends E ? ORPCErrorCode : never +type ORPCErrorsOf = E extends AnyORPCError ? E : AnyORPCError extends E ? ORPCError : never /** - * The `ORPCError`s in `E` whose code can be `TCode`, narrowed to `TCode`. - * Hidden `ORPCError` instances have unknown data. + * The codes of the `ORPCError`s a handler can receive from `E`. */ -type ORPCErrorWithCode = E extends AnyORPCError - ? E extends ORPCError - ? 0 extends (1 & UCode) - ? ORPCError - : [UCode] extends [TCode] - ? E - : [UCode & TCode] extends [never] ? never : ORPCError - : never +type ORPCErrorCodeOf = ORPCErrorsOf['code'] + +/** + * The `ORPCError`s a handler for `TCode` can receive from `E`, narrowed to + * `TCode`. Errors whose every possible code is in `TCode` are kept as is. + */ +type ORPCErrorWithCode = E extends ORPCError + ? [Exclude] extends [never] + ? E + : [UCode & TCode] extends [never] ? never : ORPCError : AnyORPCError extends E ? ORPCError : never /** * `E` without the `ORPCError`s whose every possible code is in `TCode`. */ type ExcludeORPCErrorCode = E extends ORPCError - ? 0 extends (1 & UCode) ? E : [UCode] extends [TCode] ? never : E + ? [Exclude] extends [never] ? never : E : E /** * `TCode` if it is a single literal code, `never` otherwise. */ -type LiteralORPCErrorCode = UCode extends string - ? [TCode] extends [UCode] ? Record extends Record ? never : UCode : never - : never - -/** - * The codes `TCases` handles: required, literal keys with a function value. - */ -type HandledORPCErrorCodes = { - [K in keyof TCases]-?: Record extends Pick ? never : TCases[K] extends (...args: any[]) => any ? K : never -}[keyof TCases] & string +type LiteralORPCErrorCode = Types.IsUnion extends true + ? never + : Record extends Record ? never : TCode /** * The handlers `catchORPCErrorCodes` accepts, keyed by the codes in `E`. * Non-literal codes (e.g. hidden `ORPCError` instances) become an index * signature, whose handler is bivariant so it accepts every literal handler. */ -type ORPCErrorCodeCases = { +type ORPCErrorCodeCases = Types.NoExcessProperties<{ [K in ORPCErrorCodeOf]?: Record extends Record ? { bivarianceHack(error: ORPCErrorWithCode): AnyEffect }['bivarianceHack'] : (error: ORPCErrorWithCode) => AnyEffect -} +}, TCases> + +/** + * The codes `TCases` surely handles: required keys with a function value. + */ +type HandledORPCErrorCodes = { + [K in keyof TCases]-?: TCases[K] extends (...args: any[]) => any ? K : never +}[Types.RequiredKeys] & string /** * The effects the handlers in `TCases` can return. */ -type ORPCErrorCodeCasesEffect = TCase extends (...args: any[]) => infer U ? U : never +type ORPCErrorCodeCasesEffect = ReturnType any>> + +/** + * `self` with the codes `TCases` handles caught by its handlers. + */ +type CatchORPCErrorCodesEffect = Effect.Effect< + A | Effect.Success>, + ExcludeORPCErrorCode> | Effect.Error>, + R | Effect.Services> +> /** * Recovers from `ORPCError` failures in the error channel of an effect. @@ -84,17 +95,17 @@ type ORPCErrorCodeCasesEffect = TCase exte */ export const catchORPCError: { ( - f: (error: E extends AnyORPCError ? E : AnyORPCError extends E ? ORPCError : never) => Effect.Effect, + f: (error: ORPCErrorsOf) => Effect.Effect, ): (self: Effect.Effect) => Effect.Effect, R | R2> ( self: Effect.Effect, - f: (error: E extends AnyORPCError ? E : AnyORPCError extends E ? ORPCError : never) => Effect.Effect, + f: (error: ORPCErrorsOf) => Effect.Effect, ): Effect.Effect, R | R2> } = Function.dual( 2, ( - self: Effect.Effect, - f: (error: AnyORPCError) => Effect.Effect, + self: AnyEffect, + f: (error: AnyORPCError) => AnyEffect, ) => self.pipe( Effect.catchIf((error): error is AnyORPCError => error instanceof ORPCError, f), ), @@ -137,9 +148,9 @@ export const catchORPCErrorCode: { } = Function.dual( 3, ( - self: Effect.Effect, + self: AnyEffect, code: ORPCErrorCode, - f: (error: AnyORPCError) => Effect.Effect, + f: (error: AnyORPCError) => AnyEffect, ) => self.pipe( Effect.catchIf((error): error is AnyORPCError => error instanceof ORPCError && error.code === code, f), ), @@ -173,26 +184,18 @@ export const catchORPCErrorCode: { * @see {@link https://orpc.dev/docs/integrations/effect#catching-orpcerrors | Effect Integration - Catching ORPCErrors} */ export const catchORPCErrorCodes: { - & { [K in Exclude>]: never }>( + >( cases: Cases, - ): (self: Effect.Effect) => Effect.Effect< - A | Effect.Success>, - ExcludeORPCErrorCode> | Effect.Error>, - R | Effect.Services> - > - & { [K in Exclude>]: never }>( + ): (self: Effect.Effect) => CatchORPCErrorCodesEffect + >( self: Effect.Effect, cases: Cases, - ): Effect.Effect< - A | Effect.Success>, - ExcludeORPCErrorCode> | Effect.Error>, - R | Effect.Services> - > + ): CatchORPCErrorCodesEffect } = Function.dual( 2, ( - self: Effect.Effect, - cases: Record Effect.Effect) | undefined>, + self: AnyEffect, + cases: Record AnyEffect) | undefined>, ) => self.pipe( Effect.catchIf( (error): error is AnyORPCError => error instanceof ORPCError && typeof getOwn(cases, error.code) === 'function', From 14845a6d472f205841752ff1bea25c9e3abe5363 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 17 Oct 2026 02:45:58 +0000 Subject: [PATCH 3/3] refactor(effect): drop helper comments covered by type tests Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Lg5QRphdQBu6PCo88vV51o --- packages/effect/src/error.ts | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/packages/effect/src/error.ts b/packages/effect/src/error.ts index bbc8de12fb..989d03ae09 100644 --- a/packages/effect/src/error.ts +++ b/packages/effect/src/error.ts @@ -6,46 +6,24 @@ import { Effect, Function } from 'effect' type AnyEffect = Effect.Effect -/** - * The `ORPCError`s a handler can receive from `E`. Failure types like `Error` - * can also hold hidden `ORPCError` instances, whose code and data are unknown. - */ type ORPCErrorsOf = E extends AnyORPCError ? E : AnyORPCError extends E ? ORPCError : never -/** - * The codes of the `ORPCError`s a handler can receive from `E`. - */ type ORPCErrorCodeOf = ORPCErrorsOf['code'] -/** - * The `ORPCError`s a handler for `TCode` can receive from `E`, narrowed to - * `TCode`. Errors whose every possible code is in `TCode` are kept as is. - */ type ORPCErrorWithCode = E extends ORPCError ? [Exclude] extends [never] ? E : [UCode & TCode] extends [never] ? never : ORPCError : AnyORPCError extends E ? ORPCError : never -/** - * `E` without the `ORPCError`s whose every possible code is in `TCode`. - */ type ExcludeORPCErrorCode = E extends ORPCError ? [Exclude] extends [never] ? never : E : E -/** - * `TCode` if it is a single literal code, `never` otherwise. - */ type LiteralORPCErrorCode = Types.IsUnion extends true ? never : Record extends Record ? never : TCode -/** - * The handlers `catchORPCErrorCodes` accepts, keyed by the codes in `E`. - * Non-literal codes (e.g. hidden `ORPCError` instances) become an index - * signature, whose handler is bivariant so it accepts every literal handler. - */ type ORPCErrorCodeCases = Types.NoExcessProperties<{ [K in ORPCErrorCodeOf]?: Record extends Record ? { bivarianceHack(error: ORPCErrorWithCode): AnyEffect }['bivarianceHack'] @@ -59,14 +37,8 @@ type HandledORPCErrorCodes = { [K in keyof TCases]-?: TCases[K] extends (...args: any[]) => any ? K : never }[Types.RequiredKeys] & string -/** - * The effects the handlers in `TCases` can return. - */ type ORPCErrorCodeCasesEffect = ReturnType any>> -/** - * `self` with the codes `TCases` handles caught by its handlers. - */ type CatchORPCErrorCodesEffect = Effect.Effect< A | Effect.Success>, ExcludeORPCErrorCode> | Effect.Error>,