tRPCttRPC
Powered by
ivanI
tRPC•5mo ago•
4 replies
ivan

How to map internal errors to TRPCError types?

Hi, my application is throwing it's own set of custom Errors.

Unfortunatelly tRPC always catch this errors and represent them as UNEXPECTED_SERVER_ERROR type.

I tried following:

t.procedure.use(async ({ next }) => {
  const result = await next();
  
  if (result.ok) return result;
  
  // error is already TRPCError
  result.error
})
t.procedure.use(async ({ next }) => {
  const result = await next();
  
  if (result.ok) return result;
  
  // error is already TRPCError
  result.error
})


I ended up wrapping all of my mutation/query handlers in following function:

export const appRouter = t.router({
  settingsUpdate: t.procedure.mutation(async () =>  transformErrors(() => myHandler())
});

async function transformErrors<T>(handler: () => Promise<T>) {
  try {
    return await handler();
  } catch (error) {
    if (error instanceof TRPCError) throw error;
    if (error instanceof BadRequestError)
      throw new TRPCError({
        code: "BAD_REQUEST",
        message: error.message,
      });
    if (error instanceof NotFoundError)
      throw new TRPCError({
        code: "NOT_FOUND",
        message: error.message,
      });
    if (error instanceof ForbiddenError)
      throw new TRPCError({
        code: "FORBIDDEN",
        message: error.message,
      });
    if (error instanceof UnauthorizedError)
      throw new TRPCError({
        code: "UNAUTHORIZED",
        message: error.message,
      });

    console.error(error);

    throw new TRPCError({
      code: "INTERNAL_SERVER_ERROR",
    });
  }
}
export const appRouter = t.router({
  settingsUpdate: t.procedure.mutation(async () =>  transformErrors(() => myHandler())
});

async function transformErrors<T>(handler: () => Promise<T>) {
  try {
    return await handler();
  } catch (error) {
    if (error instanceof TRPCError) throw error;
    if (error instanceof BadRequestError)
      throw new TRPCError({
        code: "BAD_REQUEST",
        message: error.message,
      });
    if (error instanceof NotFoundError)
      throw new TRPCError({
        code: "NOT_FOUND",
        message: error.message,
      });
    if (error instanceof ForbiddenError)
      throw new TRPCError({
        code: "FORBIDDEN",
        message: error.message,
      });
    if (error instanceof UnauthorizedError)
      throw new TRPCError({
        code: "UNAUTHORIZED",
        message: error.message,
      });

    console.error(error);

    throw new TRPCError({
      code: "INTERNAL_SERVER_ERROR",
    });
  }
}


I just wanted to ask if there isn't better way of doing this - eg. I believe this is exactly what middleware is supposed to do - apply code per each handler so you don't need to.

How can I get anything else than TRPCError in middleware?
tRPCJoin
Move Fast & Break Nothing. End-to-end typesafe APIs made easy.
5,015Members
Resources

Similar Threads

Was this page helpful?
Recent Announcements

Similar Threads

TRPCError that has TRPCError as cause
TkDodo 🔮TTkDodo 🔮 / ❓-help
3y ago
when throwing a TRPCError, is there a way to include an internal error code ?
Ahmed EidAAhmed Eid / ❓-help
4y ago
Customizing the TRPCError type
Emmie PäivärintaEEmmie Päivärinta / ❓-help
6mo ago
How to organise output types?
sh03Ssh03 / ❓-help
4y ago