How to do error handling in tRPC using NextJS 13 app router?

1.7k Views Asked by At

I want to avoid duplicating try/catch error handling in my procedures by creating a global error handler in tRPC.

Where are you supposed to add an onError function? The documentation for error handling says do this:

export default trpcNext.createNextApiHandler({
  // ...
  onError(opts) {
    const { error, type, path, input, ctx, req } = opts;
    console.error('Error:', error);
    if (error.code === 'INTERNAL_SERVER_ERROR') {
      // send to bug reporting
    }
  },
});

But using NextJS 13 there is no need for a next adapter so you are using the fetchRequestHandler to create a handler. Adding an onError handler here only seems to affect fetch requests on the api routes. Like fetch('localhost:3000/api/trpc/getError'). If i try calling the getError procedure using the tRPC client, the onError function is never called.

My api/trpc/[trpc]/route.ts:

import { fetchRequestHandler } from "@trpc/server/adapters/fetch";

import { appRouter } from "@/server";

const handler = (req: Request) =>
  fetchRequestHandler({
    endpoint: "/api/trpc",
    req,
    router: appRouter,
    onError: (opts) => {
      console.error("On error*********************", opts);
    },
    createContext: () => ({}),
  });

export { handler as GET, handler as POST };

My procedure in server/index.ts:

export const appRouter = router({
  getError: publicProcedure.query(() => {
    throw new Error("Test error");
  }),
...

The rest of my setup is very similar to this guide: https://levelup.gitconnected.com/next-js-13-trpc-a-match-made-in-heaven-9764fadd1084

1

There are 1 best solutions below

2
Mohamed Zaghloul On

You should throw a TRPCError instead of a standard Error.

// server/index.ts
export const appRouter = router({
  getError: publicProcedure.query(() => {
    throw new TRPCError({
      code: 'INTERNAL_SERVER_ERROR',
      message: `Test error`
    })
  }),
...