skagedal
skagedal3mo ago

Automatically decode custom errors on client

Hi! We're using tRPC v10.45.2 with React Query in a Next.js app. I'm looking for a nice way to pass custom error payloads to the browser. What I've done so far is have something like this:
export type MyAppErrorDetails = { $type: 'ILL_FORMED_BANANA'; shape: BananaShape; } | { $type: 'NOT_HUNGRY' };
export class MyAppError extends TRPCError {
public readonly details;

constructor(opts: { message?: string; code: TRPC_ERROR_CODE_KEY; cause?: unknown; details: MyAppErrorDetails }) {
super(opts);

this.details = opts.details;
}
}
export type MyAppErrorDetails = { $type: 'ILL_FORMED_BANANA'; shape: BananaShape; } | { $type: 'NOT_HUNGRY' };
export class MyAppError extends TRPCError {
public readonly details;

constructor(opts: { message?: string; code: TRPC_ERROR_CODE_KEY; cause?: unknown; details: MyAppErrorDetails }) {
super(opts);

this.details = opts.details;
}
}
Then, I create the TRPC context like this:
const t = initTRPC.context<typeof createTRPCContext>().create({
transformer: superjson,
errorFormatter({ shape, error }) {
if (error instanceof MyAppError) {
return {
...shape,
data: {
...shape.data,
details: error.details,
},
};
}
return shape;
},
});
const t = initTRPC.context<typeof createTRPCContext>().create({
transformer: superjson,
errorFormatter({ shape, error }) {
if (error instanceof MyAppError) {
return {
...shape,
data: {
...shape.data,
details: error.details,
},
};
}
return shape;
},
});
So far, all good! (Right? This is a good way to do this?) But then, on the client side, I have to do something like this everywhere:
if (error instanceof TRPCClientError) {
const { data } = error;
const { details } = data as { details: MyAppErrorDetails };
if (details.$type === 'ILL_FORMED_BANANA') {
// ....
if (error instanceof TRPCClientError) {
const { data } = error;
const { details } = data as { details: MyAppErrorDetails };
if (details.$type === 'ILL_FORMED_BANANA') {
// ....
I guess that's not that bad, but it would be nice if I could just do something like:
if (error instanceof MyAppError) {
if (error.details.$type === 'ILL_FORMED_BANANA') {
// ...
}
if (error instanceof MyAppError) {
if (error.details.$type === 'ILL_FORMED_BANANA') {
// ...
}
So – is there a way to add some kind of middleware that decodes error payloads so your onError handlers for mutations and error return value in queries could be simplified?
0 Replies
No replies yetBe the first to reply to this messageJoin