I have a component where I am fetching mock data. I am doing a query by using react-query with Suspense. I was following their docs. This is the component:
export const WorkHistory = () => {
const { caseId } = useContext();
const { api: mockApi } = useMockApi();
const { data: workHistory } = mockApi.getWorkHistory(caseId.toString());
return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
fallbackRender={({ error, resetErrorBoundary }) => (
<div>
There was an error! <Button onClick={() => resetErrorBoundary()}>Try again</Button>
<pre style={{ whiteSpace: "normal" }}>{error.message}</pre>
</div>
)}
onReset={reset}
>
<Suspense
fallback={
<div className="flex justify-center">
<Loader size="3xlarge" title="Loading..." />
</div>
}
>
<WorkHistory workHistory={workHistory} />
</Suspense>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
);
};
And this is the getWorkHistory
in mockApi:
const getWorkHistory = (caseId: string) =>
useQuery({
queryKey: `workHistory`,
queryFn: (): Promise<WorkHistoryDto[]> => fakeFetch(JSON.parse(localStorage.getItem(`workHistory`))),
staleTime: Infinity,
suspense: true,
});
const fakeFetch = (result): Promise<any> =>
new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("fail")), 1000);
});
But, this ErrorBoundary
is not catching this error. I get this:
Uncaught Error: fail
What am I doing wrong here?
You are calling useQuery
outside of the ErrorBoundary:
export const WorkHistory = () => {
// ⬇️ useQuery is called here
const { data: workHistory } = mockApi.getWorkHistory(caseId.toString());
return (
<QueryErrorResetBoundary>
{({ reset }) => (
// ⬇️ your ErrorBoundary starts here
<ErrorBoundary
...
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
);
};
The useQuery
call is what throws the error to the nearest ErrorBoundary, so it has to be inside the ErrorBoundary, not above it.
unrelated, but still important: You are violating the rules of hooks by calling useQuery
inside a function called getWorkHistory
. Hooks must be called in functional components or other hooks, so you would need to name that function useWorkHistory
or useGetWorkHistory
.