@unthrown/orpc / server
server
Server
ResultHandler
type ResultHandler<TCurrentContext, TInput, TOutput, TError, TErrorMap> = (opts, input) =>
| Result<TOutput, TError>
| Promise<Result<TOutput, TError>>
| AsyncResult<TOutput, TError>;Defined in: server.ts:40
A procedure handler that speaks Result: same options as a plain oRPC handler (input, context, errors, …), returning a Result<TOutput, TError> — synchronous, promised, or as an AsyncResult.
Type Parameters
| Type Parameter |
|---|
TCurrentContext extends Context |
TInput |
TOutput |
TError extends AnyORPCError |
TErrorMap extends ErrorMap |
Parameters
| Parameter | Type |
|---|---|
opts | ProcedureHandlerOptions<TCurrentContext, TInput, ORPCErrorConstructorMap<TErrorMap>> |
input | TInput |
Returns
| Result<TOutput, TError> | Promise<Result<TOutput, TError>> | AsyncResult<TOutput, TError>
handlerResult()
function handlerResult<TCurrentContext, TInput, TOutput, TError, TErrorMap>(handler): ProcedureHandler<TCurrentContext, TInput, TOutput, ORPCErrorConstructorMap<TErrorMap>>;Defined in: server.ts:94
Adapt a Result-returning handler into a plain oRPC procedure handler.
Type Parameters
| Type Parameter |
|---|
TCurrentContext extends Context |
TInput |
TOutput |
TError extends AnyORPCError |
TErrorMap extends ErrorMap |
Parameters
| Parameter | Type | Description |
|---|---|---|
handler | ResultHandler<TCurrentContext, TInput, TOutput, TError, TErrorMap> | the Result-speaking handler to adapt. |
Returns
ProcedureHandler<TCurrentContext, TInput, TOutput, ORPCErrorConstructorMap<TErrorMap>>
Remarks
The elimination boundary of the server half: Ok becomes the procedure's output; Err (constrained to ORPCError — build one with the injected errors.CODE(...) constructors, or map a domain error via mapErrCases first) is thrown, so a declared code reaches the client as a defined, typed error; a Defect rethrows its original cause — oRPC collapses an opaque cause to INTERNAL_SERVER_ERROR, but a bug stays a defect either way, never a typed error. A cause that is itself an ORPCError (a downstream oRPC call qualified as a defect) is wrapped in a plain Error first, so it too answers INTERNAL_SERVER_ERROR instead of its own code and status.
Like match handlers, the callback may be async (an edge elimination is exempt from the no-thenable rule): a rejection or throw inside it cannot skip triage, because oRPC's own boundary already treats it as the defect path.
Example
import { P } from "unthrown";
import { handlerResult } from "@unthrown/orpc/server";
const find = os
.input(z.object({ id: z.string() }))
.errors({ NOT_FOUND: {} })
.handler(
handlerResult(({ input, errors }) =>
repo
.findPlanet(input.id)
.mapErrCases((matcher) =>
matcher.with(P.tag("NotFound"), () => errors.NOT_FOUND()),
),
),
);