TkDodo ๐Ÿ”ฎ
TkDodo ๐Ÿ”ฎโ€ข3y ago

Error handling

We have some trpc routers that make requests to another api - we use axios for that. I'd like to forward these errors to the frontend, so if that api errors with 401, that's what I'd like to see in the browser. If I just await the request and don't catch the errors, I get a 500 error where the message is the message from the axios request. What would be the best way to handle this, globally? I wouldn't really want to wrap each api in a try / catch, and I'd also ideally not need to translate those errors to TRPCErrors...
9 Replies
Alex / KATT ๐Ÿฑ
the keys are to propagate nextjs' ctx object throughout the app & to use responseMeta
TkDodo ๐Ÿ”ฎ
TkDodo ๐Ÿ”ฎOPโ€ข3y ago
not sure I understand this ๐Ÿ˜… . I'm not really talking about SSR specifically. Just a request from the frontend going to a trpc router I'm testing with:
await axios.get('https://httpbin.org/status/401')
await axios.get('https://httpbin.org/status/401')
inside a trpc router. If I log the first clientError inside responseMeta like in your example, I'm already seeing a 500 statuscode:
TRPCClientError: Request failed with status code 401
at Function.from (/node_modules/.pnpm/@trpc+client@10.0.0-proxy-alpha.75_44ough62bf3qrmt6v2rjwsbqfm/node_modules/@trpc/client/dist/transformResult-106791d7.mjs:4:20)
at /node_modules/.pnpm/@trpc+client@10.0.0-proxy-alpha.75_44ough62bf3qrmt6v2rjwsbqfm/node_modules/@trpc/client/dist/links/httpBatchLink.mjs:189:56
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
meta: {
response: Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: [Object],
[Symbol(Response internals)]: [Object]
}
},
shape: {
message: 'Request failed with status code 401',
code: -32603,
data: {
code: 'INTERNAL_SERVER_ERROR',
httpStatus: 500,
stack: 'Error: Request failed with status code 401\n' +
TRPCClientError: Request failed with status code 401
at Function.from (/node_modules/.pnpm/@trpc+client@10.0.0-proxy-alpha.75_44ough62bf3qrmt6v2rjwsbqfm/node_modules/@trpc/client/dist/transformResult-106791d7.mjs:4:20)
at /node_modules/.pnpm/@trpc+client@10.0.0-proxy-alpha.75_44ough62bf3qrmt6v2rjwsbqfm/node_modules/@trpc/client/dist/links/httpBatchLink.mjs:189:56
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
meta: {
response: Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: [Object],
[Symbol(Response internals)]: [Object]
}
},
shape: {
message: 'Request failed with status code 401',
code: -32603,
data: {
code: 'INTERNAL_SERVER_ERROR',
httpStatus: 500,
stack: 'Error: Request failed with status code 401\n' +
Alex / KATT ๐Ÿฑ
ah i seeeeeee in the error formatting fn you can do it
Alex / KATT ๐Ÿฑ
Error Formatting | tRPC
The error formatting in your router will be inferred all the way to your client (&ย Reactย components)
Alex / KATT ๐Ÿฑ
instanceof AxiosError or whatever on the .cause and then remap it sorry i misunderstood, sometimes i snap in and out too quickly potentially you can do it in a middleware too the thing tho is that a server-to-server call that results in 401 shouldn't necessarily be a 401 for the client sometimes it should be a 500 just something to keep in mind so i usually do some mappers further "down" instead
TkDodo ๐Ÿ”ฎ
TkDodo ๐Ÿ”ฎOPโ€ข3y ago
Yeah makes sense. Thanks, I'll look into these links โค๏ธ
Alex / KATT ๐Ÿฑ
or do some safe wrapper that is like this
const result = await doAxiosShit<T>()
// ^? -> Either<T, AxiosError>
const result = await doAxiosShit<T>()
// ^? -> Either<T, AxiosError>
TkDodo ๐Ÿ”ฎ
TkDodo ๐Ÿ”ฎOPโ€ข3y ago
error formatting works, thanks