Skip to content

Commit

Permalink
docs
Browse files Browse the repository at this point in the history
  • Loading branch information
unnoq committed Jan 10, 2025
1 parent 94a742d commit 6e8b499
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 3 deletions.
64 changes: 63 additions & 1 deletion apps/content/content/docs/server/error-handling.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,70 @@
---
title: Error Handling
title: Typesafe Error Handling
description: How to intercept, handle or log errors inside oRPC
---

## Typed errors

```ts twoslash
import { createORPCReactQueryUtils } from '@orpc/react-query'
import { createProcedureClient, isDefinedError, os, safe } from '@orpc/server'

const createPost = os
.errors({
CONFLICT: {
status: 409, // (optional) default CONFLICT is 409
message: 'Conflict', // (optional)
data: z.object({ // (optional)
why: z.string(),
}),
},
// ANY_CODE: { unknown code is allowed, with default status is 500
// status: 500,
// },
})
.handler(({ errors }) => {
throw errors.CONFLICT({ data: { why: 'some reason' } })

// is the same as, but this is not typed
throw new ORPCError({ code: 'CONFLICT', data: { why: 'some reason' } })

// throw errors.ANY_CODE()
})

const client = createProcedureClient({ procedure: createPost }) // or any kind of client

const [data, error, isDefined] = await safe(client({ title: 'title' }))

if (error) {
if (isDefinedError(error)) { // or use isDefined const
const data = error.data // { why: 'some reason' } full typed data
}
else {
// any errors what not satisfy, or not defined in .errors
}
}

/// example handle error for `@orpc/react-query`

import { useMutation } from '@tanstack/react-query'
import { z } from 'zod'

const utils = createORPCReactQueryUtils(client)

const mutation = useMutation(utils.mutationOptions({
onError(error) {
if (isDefinedError(error)) {
const data = error.data // { why: 'some reason' } full typed data
}
},
}))
```

> **Note**: typesafe errors are coverage in every oRPC packages: `@orpc/client`, `@orpc/react-query`, `@orpc/vue-query`, `@orpc/vue-colada`, ...
> Please use `isDefinedError` or `safe` to typesafe handle errors. Export from `@orpc/contract`, `@orpc/server`, and `@orpc/client`.
## Handle errors

```ts twoslash
import { ORPCError, os } from '@orpc/server'

Expand Down
15 changes: 13 additions & 2 deletions apps/content/content/home/landing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ export const updateUser = os
path: '/users/{id}' // dynamic params support
method: 'PATCH' // custom OpenAPI method
})
.errors({ // End-to-end typesafe error handling
NOT_FOUND: {
data: z.object({
why: z.string(),
}),
}
})
.input(z.object({
id: z.bigint(),
user: z.object({
Expand All @@ -17,11 +24,15 @@ export const updateUser = os
}))
.output(z.literal("success")) // validate output
.use(canMiddleware, (input) => input.id) // permission check by id
.handler(async ({ input }) => /* handle user update */)
.handler(async ({ input, errors }) => {
/* handle user update */

// or throw
throw errors.NOT_FOUND({ data: { why: 'some reason' } })
})
```

> Only the `.handler` method is required. All other chain methods are optional.
>
With [Middleware](/docs/server/middleware) and the [Procedure Builder](/docs/server/procedure),
you can create **reusable logic** that ensures **type safety** and adds **power** and **flexibility** to your functions.
Expand Down

0 comments on commit 6e8b499

Please sign in to comment.