handle onError mutation

want to show a toast when an error occured, so i copy and paste theo emoji project code but somehow still showing general error, any ideas thanks
11 Replies
arete
arete2y ago
anyone ?
rocawear
rocawear2y ago
Also I think its "cleaner" to do:
if(e instanceof z.ZodError) {
console.log(e.message)
} else {
console.log(message)
}
if(e instanceof z.ZodError) {
console.log(e.message)
} else {
console.log(message)
}
Just log the e to understand what is giving your error
BootesVoid
BootesVoid10mo ago
hey did you figure this out?
Alky
Alky10mo ago
If your callback it's working, that is, putting a console.log() outputs to console, i can't know the error with the given information. But i think the problem is that your callback is not being called at all. Maybe the error throw on api side it's correct, or maybe you query is always retrying, so the erro callback it's no called until the number os retries end.
BootesVoid
BootesVoid10mo ago
yeah the callback is not triggering at all. When exactly is the onError triggerred? I've tried throwing errors on the api side but still no luck.
JulieCezar
JulieCezar10mo ago
try defining it on the query level, and not when you mutate... try, but I think it's something like this
const mutation = trpc.login.useMutation({
onError: (err) => { ... }
});
const mutation = trpc.login.useMutation({
onError: (err) => { ... }
});
and yes, throwing errors or returning errors on the server-side should trigger this onError callback
Alky
Alky10mo ago
Can you show how you're returning error on API side?
BootesVoid
BootesVoid10mo ago
deleteStrategyManagement: protectedProcedure
.input(z.object({ type: z.string(), value: z.string() }))
.mutation(({ ctx, input }) => {
const { value, type } = input
try {
if (type === "tradeentry") {
return ctx.db.entryType.deleteMany({
where: {
value: value,
},
});
} else if (type === "tradeexit") {
return ctx.db.exitType.deleteMany({
where: {
value: value,
},
});
} else if (type === "management") {
return ctx.db.management.deleteMany({
where: {
value: value,
},
});
} else {
throw new TRPCClientError("Invalid type");
}
} catch (error) {
throw new TRPCError({
code: 'BAD_REQUEST',
message: 'Duplicate Value'});
}

}),
deleteStrategyManagement: protectedProcedure
.input(z.object({ type: z.string(), value: z.string() }))
.mutation(({ ctx, input }) => {
const { value, type } = input
try {
if (type === "tradeentry") {
return ctx.db.entryType.deleteMany({
where: {
value: value,
},
});
} else if (type === "tradeexit") {
return ctx.db.exitType.deleteMany({
where: {
value: value,
},
});
} else if (type === "management") {
return ctx.db.management.deleteMany({
where: {
value: value,
},
});
} else {
throw new TRPCClientError("Invalid type");
}
} catch (error) {
throw new TRPCError({
code: 'BAD_REQUEST',
message: 'Duplicate Value'});
}

}),
Alky
Alky10mo ago
One unrelated problem is that the last else throw doesn't pass the info to the catch, since you don't use the errorof the try catch block. But anyway, throwing a TRPCERROR it's enough to trigger the error on the client. I've made a simple endpoint using the t3-app scafolder just to demonstrate:
export const postRouter = createTRPCRouter({
create: publicProcedure
.input(z.object({ name: z.string().min(1) }))
.mutation(async ({ ctx, input }) => {
// simulate a slow db call
try {
throw new TRPCClientError("Try code throw")
} catch (error) {

throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Something went wrong",
});
}

}),
});
export const postRouter = createTRPCRouter({
create: publicProcedure
.input(z.object({ name: z.string().min(1) }))
.mutation(async ({ ctx, input }) => {
// simulate a slow db call
try {
throw new TRPCClientError("Try code throw")
} catch (error) {

throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Something went wrong",
});
}

}),
});
The mutation on a client component:
const createPost = api.post.create.useMutation({
onSuccess: () => {
router.refresh();
setName("");
},
onError: (err) => {
console.log('My Client:',err);
}
});
const createPost = api.post.create.useMutation({
onSuccess: () => {
router.refresh();
setName("");
},
onError: (err) => {
console.log('My Client:',err);
}
});
The mutate call:
onSubmit={(e) => {
e.preventDefault();
createPost.mutate({ name }, {
onError: (err) => {
console.log('My Client2:',err);
}
});
}}
onSubmit={(e) => {
e.preventDefault();
createPost.mutate({ name }, {
onError: (err) => {
console.log('My Client2:',err);
}
});
}}
The console:
No description
Alky
Alky10mo ago
But if you have retry enabled:
const createPost = api.post.create.useMutation({
onSuccess: () => {
router.refresh();
setName("");
},
onError: (err) => {
console.log('My Client:',err);
},
retry: true,
retryDelay: 1000,
});
const createPost = api.post.create.useMutation({
onSuccess: () => {
router.refresh();
setName("");
},
onError: (err) => {
console.log('My Client:',err);
},
retry: true,
retryDelay: 1000,
});
This happens:
No description
Alky
Alky10mo ago
This way, the error is never thrown. If instead of retry:true you have retry:5, with e.g retryDelay:2000, it will take 10 seconds( 5 * 2000ms) + 10 error executions before the error is thrown. If retry:true, the error will never be thrown, because it will keep trying. Try setting retry: false on the query level and see if it works. If it works, you probably have to change your default query client configs.
Want results from more Discord servers?
Add your server