Skip to content

Error Handling in oRPC Clients

This guide explains how to handle type-safe errors in oRPC clients using type-safe error handling. Both server-side and client-side clients are supported.

Using safe and isDefinedError

ts
import { 
isDefinedError
,
safe
} from '@orpc/client'
const
doSomething
=
os
.
input
(
z
.
object
({
id
:
z
.
string
() }))
.
errors
({
RATE_LIMIT_EXCEEDED
: {
data
:
z
.
object
({
retryAfter
:
z
.
number
() })
} }) .
handler
(async ({
input
,
errors
}) => {
throw
errors
.
RATE_LIMIT_EXCEEDED
({
data
: {
retryAfter
: 1000 } })
return {
id
:
input
.
id
}
}) .
callable
()
const [
error
,
data
,
isDefined
] = await
safe
(
doSomething
({
id
: '123' }))
// or const { error, data, isDefined } = await safe(doSomething({ id: '123' })) if (
isDefinedError
(
error
)) { // or isDefined
// handle known error
console
.
log
(
error
.
data
.
retryAfter
)
} else if (
error
) {
// handle unknown error } else { // handle success
console
.
log
(
data
)
}

INFO

  • safe works like try/catch, but can infer error types.
  • safe supports both tuple [error, data, isDefined] and object { error, data, isDefined } styles.
  • isDefinedError checks if an error originates from .errors.
  • isDefined can replace isDefinedError

Safe Client

If you often use safe for error handling, createSafeClient can simplify your code by automatically wrapping all procedure calls with safe. It works with both server-side and client-side clients.

ts
import { createSafeClient } from '@orpc/client'

const safeClient = createSafeClient(client)

const [error, data] = await safeClient.doSomething({ id: '123' })

Released under the MIT License.