Express + tRPC: handle express errors from client

I currently have Express as backend and react on frontend. I want to migrate gradually to tRPC + react query. In order to do that I want to use the tRPC express middleware. I have tons of express middleware that I want to continue using for now, as well as error handlers. The problem is that the tRPC client (trpc react query) does not recognize express errors like custom session timeout, 401, etc, which is normal, so I get the "Unable to transform response from server". But I would like to know if there is an easy way to format express errors easily to tRPC errors, or if its possible to catch the error before tRPC client tries to transform it, so that I can handle it myself.
AK
Alex / KATT πŸ±β€’287d ago
You could potentially do a custom link that reformats error I think you have access to the response object there
R
reador23β€’287d ago
Thats a good idea, I already have a custom link but when I log the error from there its already the tRPC error "Unable to transform response from server". Maybe I'm not doing it right, do you have an example of implementation ?
AK
Alex / KATT πŸ±β€’287d ago
working on it
AK
Alex / KATT πŸ±β€’287d ago
had to add support for it https://github.com/trpc/trpc/pull/4597
GitHub
feat(client): add HTTP response object to TRPCClientError meta ...
🎯 Changes Allows you to access: error.meta?.response error.meta?.responseJSON In for instance links etc
AK
Alex / KATT πŸ±β€’287d ago
released to 10.34.0 now you should be able to do custom stuff with that based on err.meta.responseJSON
R
reador23β€’287d ago
Wow! Incredible support! Thank you so much, I will give it a try
AK
Alex / KATT πŸ±β€’287d ago
Feel free to get your employer to sponsor πŸ˜„
R
reador23β€’287d ago
Ah I wish…, but my company in japan would probably laugh to my face for asking this. For now I’m trying to sell the idea of tRPC to my managers. So still working on a PoC. Maybe if one day tRPC becomes a huge part of my company tech stack Your fix indeed works as expected, I’m still having trouble on how to do error handling depending on this response, but I think it’s because I’m new to this concept of link and how it works, like how to throw a new error.
AK
Alex / KATT πŸ±β€’286d ago
you can probably do something like this to add extra metadata to it:
class MyCustomError extends TRPCClientError<AppRouter> {
constructor(message: string) {
super(message);
}
}

function isObject(value: unknown): value is Record<string, unknown> {
// check that value is object
return !!value && !Array.isArray(value) && typeof value === 'object';
}

const customErrorLink: TRPCLink<AppRouter> = (runtime) => (opts) =>
observable((observer) => {
const unsubscribe = opts.next(opts.op).subscribe({
error(err) {
if (
err.meta &&
isObject(err.meta.responseJSON) &&
'__error' in err.meta.responseJSON
) {
// custom error handling
observer.error(
new MyCustomError(
`custom error: ${JSON.stringify(
err.meta.responseJSON.__error,
)}`,
),
);
}
observer.error(err);
},
});
return unsubscribe;
});
class MyCustomError extends TRPCClientError<AppRouter> {
constructor(message: string) {
super(message);
}
}

function isObject(value: unknown): value is Record<string, unknown> {
// check that value is object
return !!value && !Array.isArray(value) && typeof value === 'object';
}

const customErrorLink: TRPCLink<AppRouter> = (runtime) => (opts) =>
observable((observer) => {
const unsubscribe = opts.next(opts.op).subscribe({
error(err) {
if (
err.meta &&
isObject(err.meta.responseJSON) &&
'__error' in err.meta.responseJSON
) {
// custom error handling
observer.error(
new MyCustomError(
`custom error: ${JSON.stringify(
err.meta.responseJSON.__error,
)}`,
),
);
}
observer.error(err);
},
});
return unsubscribe;
});
R
reador23β€’285d ago
Oh thanks! I actually did something kind of similar, I will show you on Monday when I get back to work. It would be nice if it can help people in the future. I think its really important for people that want to migrate their big applications to tRPC as they want to be able to keep using their current code (in our case here its the error handling) and have time to gradually migrate. Maybe if I successfully do it, I could write an article or something on how I migrated a big production Express + SSR React app to tRPC.
More Posts
queries running on server even though ssr is set to falseQueries are running on server side only despite the fact of setting ssr:false. Besides that, the queTypeError: client[procedureType] is not a functionHas anyone encountered this error before? I'm trying to implement an adapter for Auth.js that can coTRPC -useInfiniteQuery() refreshes all data when an input is varied, how to use?So I have a TRPC infiniteQuery: ``` const { data, fetchNextPage, hasNextPage } = trpc.server.Cannot get server response headers in browserHi, I am working on retrieving a specific server-sent header using a custom link with tRPC. This meteventemitter not having any listeners on websocketHi, I have a app router project with TRPC but I created a websocket server alongside and a websocketRPC + cls-hookedHi, im trying to implement `cls-hooked` library with trpc's protectedProcedure, but it doesnt seem ttrpc + fastify POST request not workingI have a trpc mutation like this: ``` create: publicProcedure .input(z.object({ title: z.stringproblem with useContext (likely easy fix)```tsx function userCard( user: { id: string; name: string | null; image: string | nulI think i found an TRPC BUGI am using TRPC With Fastify and bun (node.js alternative) if you try to call any .mutation route thuseMutation in useEffect dependency array causes infinite loopI had a very unexpected issue today when testing out some code. I have a simple `sum` method in tRPChow does batching work?My understanding is that batching basically combines multiple requests in a single network request, Links vs MiddlewaresWhat is the difference between a middleware and a link? These two seems to behave the same?Setting up tRPC with Supabase and DrizzleHi! πŸ˜„ Is there someone that has any recommendations on how I should setup tRPC with Supabase Auth aRequests running multiple times after it's failingCannot read properties of undefined (reading 'trpc')I keep getting that when trying to make an api request with my next.js page. I am using the latest NDoes SSG / ServerSideHelpers allow for mutations in getServerSideProps Nextjs ?Hi, I have a use case where I send the user to a payment portal, and the payment portal can send theCan someone explain MiddlewareFunction?I am trying to create a custommiddleware.ts file and I would like some explanation on what goes intoHow do I get the queries and mutations list in v10?Hello, In tRPC v9 I can do: ``` const queries = Object.keys(appRouter._def.queries); const mutatiIssues with subrouters being treated as any on clientI have 3 sub routers, all with a hello query just returning an object with world. I'm using nextjs wStrange trpc typesHello, I just installed a fresh `trpc` project with `prisma` and `next`. I have a prisma schema such