T
TanStack2y ago
absent-sapphire

Error Handling with Fetch works but isError always returns False

So I am using NextJS with page router, and in my code, I have an API that can return either a status 200 with the data or several other status codes (404, 403, and 500) depending on access permissions. Following the docs, I wrote my react query function as follows:
export async function getPlanFn(planId: string) {
const res = await fetch(`/api/controllers/plan?planId=${planId}`);

if (!res.ok) {
const error = (await res.json()) as Error;
throw new Error(error.message);
// return Promise.reject(error.message);
}

return res.json()
}

export function useGetPlan(planId: string) {

return useQuery({
queryKey: ["plan", "123"],
queryFn: () => getPlanFn(planId),
enabled: planId !== undefined || planId !== null,
refetchInterval: 1000 * 10, // get new data every 10 secs
});
}
export async function getPlanFn(planId: string) {
const res = await fetch(`/api/controllers/plan?planId=${planId}`);

if (!res.ok) {
const error = (await res.json()) as Error;
throw new Error(error.message);
// return Promise.reject(error.message);
}

return res.json()
}

export function useGetPlan(planId: string) {

return useQuery({
queryKey: ["plan", "123"],
queryFn: () => getPlanFn(planId),
enabled: planId !== undefined || planId !== null,
refetchInterval: 1000 * 10, // get new data every 10 secs
});
}
and my I access this function on my [plan].tsx page as such:
const {
isLoading,
isError,
error,
data: trip,
} = useGetPlan(planId as string);
const {
isLoading,
isError,
error,
data: trip,
} = useGetPlan(planId as string);
I'm finding that the error shows up from getPlanFn, but isError is always FALSE (please see photo for reference). Why might that be happening? I would appreciate the help on this because I've been struggling for the past 2 hours, trying to figure out what is wrong.
No description
12 Replies
sensitive-blue
sensitive-blue2y ago
it goes to isError: true after 3 retries which you can of course customize
absent-sapphire
absent-sapphireOP2y ago
it still says isError
No description
absent-sapphire
absent-sapphireOP2y ago
and the status remains in pending
No description
sensitive-blue
sensitive-blue2y ago
sorry I can't help from just screenshots. show a running reproduction, because there's something missing you're not telling. Like, errorCount is 10, but error is still null. Seems like you do infinite retries? Have you changed the customization of that? and have you tried turning off the interval? I doubt that that helps, but if you refetch after 10 seconds and the retries take longer, this might be it. It shouldn't though
absent-sapphire
absent-sapphireOP2y ago
Ok I'll make a reproduction real quick on sandbox. Even when I set retry:1 i'm still getting the same result, same goes for turning off the interval give me a sec gotta paste code XD codesandbox is extremely infuriating. Only just found a NextJs Page Router with Typescript Template @TkDodo 🔮 sorry for the wait. I had to rewrite alot of the template and get rid of other dependencies that do not affect the example. Here is the reproduction, and I'm still seeing the issue persist: https://codesandbox.io/p/devbox/practical-shadow-9pmknv?file=%2Fpages%2F_app.tsx%3A14%2C15
absent-sapphire
absent-sapphireOP2y ago
No description
sensitive-blue
sensitive-blue2y ago
what makes you do this?
void queryClient.invalidateQueries();

return useQuery({
void queryClient.invalidateQueries();

return useQuery({
invalidate is a side-effect that triggers a refetch that explains everything 🙃 your comment:
// invalidate the query when the tripId changes
that's not what this is doing
absent-sapphire
absent-sapphireOP2y ago
Oh ok i will remove that. I wrote that prior to considering error handling and so it did not affect results I'll be able to check if this solves the issue and will respond later. Hopefulky this is the fix, but in any case thank you @TkDodo 🔮 for the help so far haha. I was just reading your error handling article right before hopping on discord XD @TkDodo 🔮 I just got home and removed the invalidateQuery and it works 🙂 Thank you so much! It was so dumb of me to have that line XD
sensitive-blue
sensitive-blue2y ago
great 👍 . it emphasizes why reproductions are necessary, because you didn't show that line of code in the snippets 🙂 thanks for taking the time to reproduce it in isolation 👍
absent-sapphire
absent-sapphireOP2y ago
also, @TkDodo 🔮 one final question is that I renabled refreshInterval and I'm finding that obviously it is refreshing. Is there any way to simply disable this refreshinterval should I get certain statusCode? This is using fetch and not axios...
sensitive-blue
sensitive-blue2y ago
refetchInterval can be a function so:
refetchInterval: (query) => check query.state here
refetchInterval: (query) => check query.state here
actually transforming the failed fetch into some error that contains the status code is something you have to do if you don't use a lib because fetch itself doesn't do that use ky 😉
absent-sapphire
absent-sapphireOP2y ago
🙂 thanks

Did you find this page helpful?