Custom error management
Hey peeps! I could've sworn I created a GitHub issue about this, but I must've been dreaming, because I cannot find it. Anyway, it's support-related, so I figured it's better to ask here!
I have a large application that has a traditional client/server API and I use Axios to make calls to the server. Now, I'm investigating replacing that with tRPC (because it feels like an amazing developer experience and will quicken development). I have a rather "sophisticated" error management in the application. I have my own custom
ApplicationError
, which has an errorCode
and a custom data
object with additional information about the error. Any server-side code in the application can throw this error. A middleware catches this and converts it to a 400 Bad Request with an appropriate JSON response body.
In the client, I also have my custom wrapper on top of Axios, that simply catches 400 Bad Request, and converts the JSON back to an ApplicationError
and simply throws it. This means that I can easily catch ApplicationError
in my client side code, just as if it was originally thrown on the client.
Now, I want to do something similar with tRPC. I see that we have the TRPCError
, but I would love to be able to utilize my ApplicationError
. For two reasons:
1. I don't want to re-write all my code.
2. I think it's a nice abstract layer that the majority of my server side code do not need to be aware of "tRPC".
Does anyone have any ideas on how I can achieve this? I would need some kind of middleware on top of the tRPC procedure that catches my error and converts it into a TRPCError
. I would also need some kind of filter in my tRPC client code that automatically converts this back into an ApplicationError
and throws it.
Any help or suggestions are appreciated! Thanks in advance.14 Replies
errorFormatter and middlewares should do the trick
You can remove a lot of your boilerplate because youβve essentially described how tRPC handles errors too, albeit you probably wonβt get back an instanceof your custom error class, just can add your extra data no problem
An error catching middleware like before should be possible
Allright, I'll look into it, thanks Nick!
Did you figure this out @anton-johansson ? I'm using sveltekit and in order to redirect we need to throw unwrapped errors. @Nick Lucas any ideas how to get an unwrapped error out?
Hmm, I'm still struggling a little bit with this. Is there no way to convert it back to my own custom error on the client side, in a "generic" way?
It feels like it should be relatively easy to hook in where the error object is being created, and convert it back to my own error type.
@Nick Lucas Any ideas? Digging deep into the tRPC code at the moment, and it looks like the error must be of type
TRPCClientError<MyRouter>
. Otherwise, I could probably write my own httpBatchLink
with custom error logic, but it looks like I can't.I believe you could set up your transformer to achieve this
Superjson can have custom types registered
But it would be simpler to include a type key on the change so you can check the type of the error on the frontend
Well, I mostly want this because I feel it's clearer to handle my own error than a library-specific error. π But it probably does not matter much.
Anyway, I tried messing around with transformer, but it looks like the entire framework is tightly coupled with the
TRPCClientError
type. The TRPCLink
type "forces" TRPCClientError
.
I'll see if I can easily work with TRPCClientError
instead.All our errors I believe have cause keys, your error will be contained within and you can access it in the error formatter
Yeah, but I'd love to be able to do something like this:
But I think this won't work, I'll have to work with the
TRPCClientError
.Feel free to open a github issue, and PRs are welcome π
I had some thoughts first, but I think I can make it very similar with the
TRPCClientError
, I'm gonna mess around a bit with it. π
I just like the idea of having the same error on the server and on the client, but it's more a personal thing.I suspect the benefit isn't that clear though, using the error formatter to output an object with a type string you can switch on will produce the same effect, and serialising errors even with a transformer is likely to be a nightmare
Yeah I get it, I just figured that you could allow "converting" a TRPCClientError into my own error before throwing it, but I'm not sure if it's worth the effort.
TRPCClientError does have a cause key by the way, worth checking if that already contains what you want
Yeah I'll check!
Looks like the
cause
is undefined
here
So I'd have to work with the data
instead, which is most likely fine. π