Error Formatting

The error formatting in your router will be inferred all the way to your client (& React components)

Usage example highlighted

Adding custom formatting

server.ts

  1. const router = trpc.router<Context>()
  2. .formatError(({ shape, error }) => {
  3. return {
  4. ...shape,
  5. data: {
  6. ...shape.data,
  7. zodError:
  8. error.code === 'BAD_USER_INPUT' &&
  9. error.cause instanceof ZodError
  10. ? error.cause.flatten()
  11. : null,
  12. };
  13. };
  14. })

Usage in React

components/MyComponent.tsx

  1. export function MyComponent() {
  2. const mutation = trpc.useMutation('addPost');
  3. useEffect(() => {
  4. mutation.mutate({ title: 'example' });
  5. }, []);
  6. if (mutation.error?.data?.zodError) {
  7. // zodError will be inferred
  8. return (
  9. <pre>Error: {JSON.stringify(mutation.error.data.zodError, null, 2)}</pre>
  10. );
  11. }
  12. return <>[...]</>;
  13. }

All properties sent to formatError()

Since v8.x tRPC is compliant with JSON-RPC 2.0

  1. {
  2. error: TRPCError;
  3. type: ProcedureType | 'unknown';
  4. path: string | undefined;
  5. input: unknown;
  6. ctx: undefined | TContext;
  7. shape: DefaultErrorShape; // the default error shape
  8. }

DefaultErrorShape:

  1. interface DefaultErrorData {
  2. code: TRPC_ERROR_CODE_KEY;
  3. httpStatus: number;
  4. path?: string;
  5. stack?: string;
  6. }
  7. interface DefaultErrorShape
  8. extends TRPCErrorShape<TRPC_ERROR_CODE_NUMBER, DefaultErrorData> {
  9. message: string;
  10. code: TRPC_ERROR_CODE_NUMBER;
  11. }