feat(contract): error factory - #1760
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
More templates
@orpc/ai-sdk
@orpc/arktype
@orpc/bun
@orpc/client
@orpc/cloudflare
@orpc/contract
@orpc/experimental-effect
@orpc/evlog
@orpc/json-schema
@orpc/nest
@orpc/next
@orpc/openapi
@orpc/opentelemetry
@orpc/pinia-colada
@orpc/pino
@orpc/publisher
@orpc/ratelimit
@orpc/server
@orpc/shared
@orpc/swr
@orpc/tanstack-query
@orpc/trpc
@orpc/valibot
@orpc/zod
commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
ℹ️ Minor suggestions and observations. No blocking issues.
Reviewed changes — a new error() factory in @orpc/contract, relocation of createORPCErrorConstructorMap from @orpc/server to @orpc/contract, and associated import/export updates, tests, and docs.
error()factory — creates classes extendingORPCErrorwith bound code, default message, and optional data schema.instanceofmatches by code + data validation, not constructor identity. Async data schemas throwTypeError.ErrorMapItemsimplified — dropped the generic parameter;ORPCErrorFromErrorMapandORPCErrorConstructorMapnow access.datadirectly.createORPCErrorConstructorMaprelocated — moved from@orpc/serverto@orpc/contract; server re-exports. Works correctly with factory items registered under their code.- OpenAPI + e2e coverage — factory items render correctly in generated specs;
defined: truepropagates through the full handler → wire → client round trip.
ℹ️ ErrorMapItem generic removal
ErrorMapItem lost its generic type parameter (ErrorMapItem<TDataSchema> → ErrorMapItem). This is a breaking change for any external code that referenced ErrorMapItem<SomeSchema>. All internal usages are updated within this PR and no external callers are visible in the impact analysis, so the blast radius is minimal. Worth noting for the changelog.
Note: 1 inline comment(s) dropped because they did not anchor to lines inside the PR diff:
packages/contract/src/error-factory.ts:523(RIGHT) — line 523 (RIGHT) is not inside a diff hunk
DeepSeek Pro (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — the error() factory signature was refactored to take code as a positional argument instead of inside the options object.
error(code, options?)signature —error('RATE_LIMITED', { data: ... })replaceserror({ code: 'RATE_LIMITED', data: ... }).error('SIMPLE')works for bare-code factories with no data schema.ORPCErrorFactoryOptionsdropped itscodefield and the<TCode>generic parameter.- Updated all call sites — tests, docs, and OpenAPI unit test use the new signature. JSDoc updated with separate
@param codeand@param optionstags.
DeepSeek Pro (free via Pullfrog for OSS) | 𝕏

Adds an
error()factory to@orpc/contractthat creates reusableORPCErrorclasses bound to a code, default message, and data schema. A factory class can be thrown anywhere, registered directly in.errors()under its code, and checked withinstanceofwith full type narrowing. ThecreateORPCErrorConstructorMaputilities also move from@orpc/serverinto@orpc/contractso the whole error map machinery lives in one package.Features
const RateLimitedError = error('RATE_LIMITED', { message, data })—throw new RateLimitedError({ data })works in handlers, middleware, or plain utilities and still reconciles into the typesafe error flow via ORPCError compatibility. The signature mirrorsnew ORPCError(code, options), and the options are optional:error('UNAUTHORIZED')is enough for a bare code.instanceofmatches anyORPCErrorwith the same code whose data passes the schema, even instances the class did not create, and narrows toORPCError<Code, Data>. Async data schemas throw a descriptiveTypeErrorinstead of silently misbehaving.ErrorMapItem, so[RateLimitedError.code]: RateLimitedErrorin.errors()renders them in generated OpenAPI documents.error,ORPCErrorFactory, andORPCErrorFactoryOptionsare re-exported from@orpc/server.Testing
instanceofedge cases and optional-data constructor signatures.definedflag survives the full handler → wire → client round trip on both hono-fetch and node-http transports.Docs
instanceofsubsection) in the error handling guide;ErrorMapItemand the factory APIs gained JSDoc with links back to it.