Skip to content

@unthrown/orpc


@unthrown/orpc / server

server ​

Server ​

ResultHandler ​

ts
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 ​

ParameterType
optsProcedureHandlerOptions<TCurrentContext, TInput, ORPCErrorConstructorMap<TErrorMap>>
inputTInput

Returns ​

| Result<TOutput, TError> | Promise<Result<TOutput, TError>> | AsyncResult<TOutput, TError>


handlerResult() ​

ts
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 ​

ParameterTypeDescription
handlerResultHandler<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 ​

ts
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()),
        ),
    ),
  );

Released under the MIT License.