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
import { initTRPC } from '@trpc/server';
export const t = initTRPC<{ ctx: Context }>()({
  errorFormatter({ shape, error }) {
    return {
      ...shape,
      data: {
        ...shape.data,
        zodError:
          error.code === 'BAD_USER_INPUT' &&
          error.cause instanceof ZodError
            ? error.cause.flatten()
            : null,
      };
    };
  }
})
Usage in React​
components/MyComponent.tsx
export function MyComponent() {
  const mutation = trpc.proxy.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()​
Since
v8.xtRPC is compliant with JSON-RPC 2.0
{
  error: TRPCError;
  type: ProcedureType | 'unknown';
  path: string | undefined;
  input: unknown;
  ctx: undefined | TContext;
  shape: DefaultErrorShape; // the default error shape
}
DefaultErrorShape:
interface DefaultErrorData {
  code: TRPC_ERROR_CODE_KEY;
  httpStatus: number;
  path?: string;
  stack?: string;
}
interface DefaultErrorShape
  extends TRPCErrorShape<TRPC_ERROR_CODE_NUMBER, DefaultErrorData> {
  message: string;
  code: TRPC_ERROR_CODE_NUMBER;
}