I use an infinite list for which I prefetch data on the app startup. Everything works great except for when I hit 404 error if, for example, I manually change the url to a wrong one. Then the whole app breaks and throws errors in console.
I understand that I could use fetchQuery
to handle errors but I am satisfied with how prefetch works. I also know that it doesn't return anything so what are my options to handle 404 when prefetching with prefetchQuery
? Seems strange that it just breaks everything.
How to handle a scenario when the code is fine but backend went offline, for example?
To be honest, I intuitively thought that in case of problems the prefetch would just skip.
const initialPageParam = "api/v1/logs-list/json/?limit=25&offset=0";
const queryFn = async (pageParam: string, customKy: KyInstance) => {
const link = pageParam.split("a1pi/v1/")[1];
const resolvedLink = `${link}&resolved=false`;
return await customKy.get<LogsResponse>(resolvedLink).json();
};
export const usePrefetchInfiniteLogsQuery = () => {
const { customKy } = useKy();
usePrefetchInfiniteQuery({
queryKey: ["infiniteLogs", customKy],
queryFn: async ({ pageParam }) => queryFn(pageParam, customKy),
initialPageParam,
getNextPageParam: (lastPage) => lastPage?.next,
pages: 3,
});
};
export const useInfiniteLogsQuery = () => {
const { customKy } = useKy();
return useSuspenseInfiniteQuery({
queryKey: ["infiniteLogs", customKy],
queryFn: async ({ pageParam }) => queryFn(pageParam, customKy),
initialPageParam,
getNextPageParam: (lastPage) => lastPage?.next,
});
};
Here's the parent component with prefetch and then I call useSuspenseQuery
in SosForm
const SosFormWrapper = () => {
usePrefetchSosQuery();
return (
<Suspense fallback={<Loader />}>
<EmergencyModal />
<SosForm />
</Suspense>
);
};
The docs say that:
The prefetch functions never throws errors because they usually try to fetch again in a useQuery which is a nice graceful fallback.
But instead it just breaks. How do I fallback on useSuspenseQuery
?
The prefetching doesn’t fail - errors are caught internally. My guess is that the component itself that uses useInfiniteLogsQuery
then triggers another fetch (because there is nothing in the cache when it starts), or it picks up on the prefetch (meaning it will re-use the ongoing promise instead of triggering a new one).
In both cases, it would then see the error and throw to an error boundary as it uses suspense
.