skagedalS
tRPC2y ago
1 reply
skagedal

Automatically decode custom errors on client

Hi! We're using tRPC v10.45.2 with React Query in a Next.js app. I'm looking for a nice way to pass custom error payloads to the browser. What I've done so far is have something like this:

export type MyAppErrorDetails = { $type: 'ILL_FORMED_BANANA'; shape: BananaShape; } | { $type: 'NOT_HUNGRY' }; 
export class MyAppError extends TRPCError {
  public readonly details;

  constructor(opts: { message?: string; code: TRPC_ERROR_CODE_KEY; cause?: unknown; details: MyAppErrorDetails }) {
    super(opts);

    this.details = opts.details;
  }
}


Then, I create the TRPC context like this:
const t = initTRPC.context<typeof createTRPCContext>().create({
  transformer: superjson,
  errorFormatter({ shape, error }) {
    if (error instanceof MyAppError) {
      return {
        ...shape,
        data: {
          ...shape.data,
          details: error.details,
        },
      };
    }
    return shape;
  },
});


So far, all good! (Right? This is a good way to do this?)

But then, on the client side, I have to do something like this everywhere:

if (error instanceof TRPCClientError) {
  const { data } = error;
  const { details } = data as { details: MyAppErrorDetails };
  if (details.$type === 'ILL_FORMED_BANANA') {
     // ....


I guess that's not that bad, but it would be nice if I could just do something like:

if (error instanceof MyAppError) {
  if (error.details.$type === 'ILL_FORMED_BANANA') {
     // ...
}


So – is there a way to add some kind of middleware that decodes error payloads so your
onError
handlers for mutations and
error
return value in queries could be simplified?
Was this page helpful?