Search code examples
typescripthttperror-handlingtrpct3

How to prevent stack attributes on tRPC response?


I'm building a POC using T3 Framework which uses tRPC and can't find a way to prevent the stack propriety on the HTTP response. I tried to set NODE_ENV to "production" and still get the stack trace sposed to the frontend.

PS: when the template is found, I don't need extra error handling, my problem is exactly when template repository doesn't return a valid template.

PS2: I made some simplifications just to get to the point, this code reproduces the problem I facing.

My code:

export const templatesRouter = createTRPCRouter({
  get: publicProcedure
    .input(z.object({id: z.string().min(3)}))
    .query(async ({input}) => {
      const template = await TemplateRepository.get(input.id);
      if(!template) throw new TRPCError({
        code: 'NOT_FOUND',
        message: 'Template not found',
      })
      return template
    }),
});

The response I get:

{
  "error": {
    "json": {
      "message": "Template not found",
      "code": -32004,
      "data": {
        "code": "NOT_FOUND",
        "httpStatus": 404,
        "stack": "TRPCError: Template not found\n    at eval (webpack-internal:///(rsc)/./src/server/api/routers/templates.ts:46:30)...",
        "path": "templates.get",
        "zodError": null
      }
    }
  }
}

I expect:

{
  "error": {
    "json": {
      "message": "Template not found",
      "code": -32004,
      "data": {
        "code": "NOT_FOUND",
        "httpStatus": 404,
        "path": "templates.get",
        "zodError": null
      }
    }
  }
}

Solution

  • Can't you just override the stack on the error object?

    const x = new TRPCError({ code: "CONFLICT" });
    if(isProd) x.stack = "";
    
    

    or use a centralized errorFormatter: https://trpc.io/docs/server/error-formatting

    export const trpc = initTRPC.context<Context>().create({
      errorFormatter({ shape }) {
        return {
          ...shape,
          data: {
            ...shape.data,
            stack: isProd ? '' : shape.data.stack
          },
        };
      },
    });
    

    If you use the Next-TRPC adapter there seems to be an additional way of doing this. I did not use or test this way. https://trpc.io/docs/server/error-handling#handling-errors