skip to Main Content

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?

2

Answers


  1. I am not sure but I think Error Boundary is not able to catch asynchronous errors according to this article: https://blog.logrocket.com/handling-javascript-errors-react-error-boundaries/

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search