rembrembdocs

The error formatting in your router will be inferred all the way to your client.

Usage example highlighted

Adding custom formatting

server.ts

ts

import { initTRPC } from '@trpc/server';

import { ZodError } from 'zod';

export const t = initTRPC.create({

errorFormatter(opts) {

`const { shape, error } = opts;`

`return {`

  `...shape,`

  `data: {`

    `...shape.data,`

    `zodError:`

      `error.code === 'BAD_REQUEST' && error.cause instanceof ZodError`

        `? error.cause.flatten()`

        `: null,`

  `},`

`};`

},

});

Usage in React

components/MyComponent.tsx

tsx

import { useEffect } from 'react';

import { trpc } from '../utils/trpc';

export function MyComponent() {

const mutation = trpc.addPost.useMutation();

useEffect(() => {

`mutation.mutate({ title: 'example' });`

}, []);

if (mutation.error?.data?.zodError) {

`// zodError will be inferred`

`return (`

  `<pre>Error: {JSON.stringify(mutation.error.data.zodError, null, 2)}</pre>`

`);`

}

return <>[...]</>;

}

All properties sent to errorFormatter()

tRPC is compliant with JSON-RPC 2.0

ts

interface ErrorFormatterOpts {

error: TRPCError;

type: 'query' | 'mutation' | 'subscription' | 'unknown';

path: string | undefined;

input: unknown;

ctx: unknown;

shape: { message: string; code: number; data: unknown };

}

DefaultErrorShape:

ts

type DefaultErrorData = {

code: TRPC_ERROR_CODE_KEY;

httpStatus: number;

/**

* Path to the procedure that threw the error

*/

path?: string;

/**

* Stack trace of the error (only in development)

*/

stack?: string;

};

interface DefaultErrorShape {

message: string;

code: TRPC_ERROR_CODE_NUMBER;

data: DefaultErrorData;

}