Handling errors on the front-end

I'm making a mutation from my front-end and I intentionally throw a new TRPCError on my backend, I can see the trpc error on both client and server console but I don't understand how to catch it in the front-end The mutation onError does nothing, myMutation.isError is false, myMutation.error is null and status "idle" Here's some example code
const sendMessage = api.chatgpt.sendMessage.useMutation({
onError: (error) => {
console.log("error hit", error); //Doesn't execute
setLoadingResponse(false);
},
});
const sendMessage = api.chatgpt.sendMessage.useMutation({
onError: (error) => {
console.log("error hit", error); //Doesn't execute
setLoadingResponse(false);
},
});
And then on my code
sendMessage.mutate({ message: inputRef.current.value, chatId });
sendMessage.mutate({ message: inputRef.current.value, chatId });
How I throw the error
if (result.status === 200) { //Yes 200 is on purpose so I can test it
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "OpenAI API Error",
});
}
if (result.status === 200) { //Yes 200 is on purpose so I can test it
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "OpenAI API Error",
});
}
I also tried this
try {
sendMessage.mutate({ message: inputRef.current.value, chatId });
} catch (cause) {
if (isTRPCClientError(cause)) {
// `cause` is now typed as your router's `TRPCClientError`
// Nothing gets printed
console.log('data', cause.data);

}
}
try {
sendMessage.mutate({ message: inputRef.current.value, chatId });
} catch (cause) {
if (isTRPCClientError(cause)) {
// `cause` is now typed as your router's `TRPCClientError`
// Nothing gets printed
console.log('data', cause.data);

}
}
Pretty sure I'm just missing something here so a little help would be appreciated, thank you!
N
Nick307d ago
If it’s not reaching the frontend then most likely your backend isn’t actually throwing the error, or some middleware is swallowing it Check the API-side onError and errorFormatter callbacks are receiving it
O
outis99307d ago
I can see it on my frontend console
O
outis99307d ago
Server-side onError receives it as well as the error formatter But as you can see on the image all the error values are false/null I looked through all the files but can't seem to find something that swallows it @nlucas
N
Nick307d ago
Okay yeah it’s sending a 500 back so looks like that’s fine It looks like it should be calling the useMutation callback right now To catch imperatively you should await mutateAsync though
O
outis99304d ago
Even that doesn't work, I'm sorry but I can't see what I am missing here and why throwing an error from the server is so difficult to handle on the client. All of the tRPC settings and files are default and I haven't changed any error formatters or loggerlinks or whatever, should I post a git issue for this maybe?
D
Dani;304d ago
Post your trpc & react-query instantiation code on the client
O
outis99302d ago
On my _app.tsx export default api.withTRPC(MyApp); The api file
/**
* This is the client-side entrypoint for your tRPC API. It is used to create the `api` object which
* contains the Next.js App-wrapper, as well as your type-safe React Query hooks.
*
* We also create a few inference helpers for input and output types.
*/
import { httpBatchLink, loggerLink } from "@trpc/client";
import { createTRPCNext } from "@trpc/next";
import { type inferRouterInputs, type inferRouterOutputs } from "@trpc/server";
import superjson from "superjson";

import { type AppRouter } from "src/server/api/root";

const getBaseUrl = () => {
if (typeof window !== "undefined") return ""; // browser should use relative url
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`; // SSR should use vercel url
return `http://localhost:${process.env.PORT ?? 3000}`; // dev SSR should use localhost
};

/** A set of type-safe react-query hooks for your tRPC API. */
export const api = createTRPCNext<AppRouter>({
config() {
return {
/**
* Transformer used for data de-serialization from the server.
*
* @see https://trpc.io/docs/data-transformers
*/
transformer: superjson,

/**
* Links used to determine request flow from client to server.
*
* @see https://trpc.io/docs/links
*/
links: [
httpBatchLink({
url: `${getBaseUrl()}/api/trpc`,
}),
],
};
},
/**
* Whether tRPC should await queries when server rendering pages.
*
* @see https://trpc.io/docs/nextjs#ssr-boolean-default-false
*/
ssr: false,
});

/**
* Inference helper for inputs.
*
* @example type HelloInput = RouterInputs['example']['hello']
*/
export type RouterInputs = inferRouterInputs<AppRouter>;

/**
* Inference helper for outputs.
*
* @example type HelloOutput = RouterOutputs['example']['hello']
*/
export type RouterOutputs = inferRouterOutputs<AppRouter>;
/**
* This is the client-side entrypoint for your tRPC API. It is used to create the `api` object which
* contains the Next.js App-wrapper, as well as your type-safe React Query hooks.
*
* We also create a few inference helpers for input and output types.
*/
import { httpBatchLink, loggerLink } from "@trpc/client";
import { createTRPCNext } from "@trpc/next";
import { type inferRouterInputs, type inferRouterOutputs } from "@trpc/server";
import superjson from "superjson";

import { type AppRouter } from "src/server/api/root";

const getBaseUrl = () => {
if (typeof window !== "undefined") return ""; // browser should use relative url
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`; // SSR should use vercel url
return `http://localhost:${process.env.PORT ?? 3000}`; // dev SSR should use localhost
};

/** A set of type-safe react-query hooks for your tRPC API. */
export const api = createTRPCNext<AppRouter>({
config() {
return {
/**
* Transformer used for data de-serialization from the server.
*
* @see https://trpc.io/docs/data-transformers
*/
transformer: superjson,

/**
* Links used to determine request flow from client to server.
*
* @see https://trpc.io/docs/links
*/
links: [
httpBatchLink({
url: `${getBaseUrl()}/api/trpc`,
}),
],
};
},
/**
* Whether tRPC should await queries when server rendering pages.
*
* @see https://trpc.io/docs/nextjs#ssr-boolean-default-false
*/
ssr: false,
});

/**
* Inference helper for inputs.
*
* @example type HelloInput = RouterInputs['example']['hello']
*/
export type RouterInputs = inferRouterInputs<AppRouter>;

/**
* Inference helper for outputs.
*
* @example type HelloOutput = RouterOutputs['example']['hello']
*/
export type RouterOutputs = inferRouterOutputs<AppRouter>;
Also previously when I mentioned that settings are default I mean the default t3 stack configuration @s.daniel Let me know if you need anything else
More Posts
TypeScript Alias Imports don't get resolved ont the ClientI have a Monorepo with a multiple `/packages/*` packages, each has its own `tsconfig.json`. I noticmerging other routers to appRouterHey everyone, I am using the https://icflorescu.github.io/trpc-sveltekit package in my SvelteKit proCan I get non-redacted INTERNAL_SERVER_ERRORS in production?I'm trying to debug crashes in production, and having a hard time. As far as I can tell, errors are Error handling: Zod errors and manually thrown TRPCErrors have different shapeIf zod validation fails, the client-side `error.message` contains a JSON encoded array of errors, buprefetch() within getServerSideProps does not provide data upon manual refreshingWithin getServerSideProps: `await ssh.user.getDepositInfo.prefetch(userId);` `await ssh.user.getFQOHow to modify existing cache data?I have a message queue being fetched with InfiniteQuery requests. When adding a new message, I want When using createServerSideHelpers can the context be typed as GetServerSidePropsContext?I assume the reason we should recreate the context when using createServerSideHelpers is because theQuery data is undefined for a bit and is then populated. How to use with React State?I have an asychronous submit function that's called upon a button press. It refetches the query witshould we use tRPC for handling form submittion or not?Hey everyone, I've started using tRPC for my API endpoints and my project is based in Svelte/SvelteKWhat's the benefit of using the context instead of a direct import for the database connection?I've wondered why I should use the tRPC context instead of just importing my database singleton fromUsing both tRPC React client AND tRPC React Query clientHey all! We are successfully using both the React client and the React Query client. We do this becaTRPCClientErrorlike no name propertyQuick question: Why doesn't TRPCClientErrorLike have the name property? It is called ErrorLike, so IapplyWSSHandler yells at context error in expressI used the example code from docs. My applyWSSHandler code is: ``` const handler = applyWSSHandler({How to use the errorFormatter when using an adapter?The example here uses `context.create()`, which isn't something you do when using an adapter. I donOne file per function call on the server sideI'd like to structure my server with one file per function call -- is this an antipattern? If not, dOptimistic update on infinite queryNode 18.12.1 with pnpm trpc v 10.28.1 I have the following query to render a list of posts ```tsx Creating trpc context (express server) for testing without req and res objects.I have seen a few examples of tests with next auth or t3 stack that is using next-auth under the hooDoes trpc (t3 stack) disable ssr from Nextjs?Or is the ssr just not applied to the apiWhat is error formatingI understand error handeling but what is error formating , found it in trcp docs have'nt seen that twhere does opts.path and opts.type came from ? i guess by default it only stores ctx ,next and input```ts const loggerMiddleware = middleware(async (opts) => { const start = Date.now();   const re