From 3981f5219a1e3d8f48d13108b55673dcaea46319 Mon Sep 17 00:00:00 2001 From: Dominik Dorfmeister <office@dorfmeister.cc> Date: Fri, 17 Dec 2021 12:54:54 +0100 Subject: [PATCH] fix(query): set error to null when going to loading state (#3106) to be aligned with the types, as `loading` cannot have an `error` set. --- src/core/query.ts | 5 +- src/react/tests/useQuery.test.tsx | 76 +++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/src/core/query.ts b/src/core/query.ts index 1b5a3854ad..3ad311054a 100644 --- a/src/core/query.ts +++ b/src/core/query.ts @@ -584,7 +584,10 @@ export class Query< fetchMeta: action.meta ?? null, isFetching: true, isPaused: false, - status: !state.dataUpdatedAt ? 'loading' : state.status, + ...(!state.dataUpdatedAt && { + error: null, + status: 'loading', + }), } case 'success': return { diff --git a/src/react/tests/useQuery.test.tsx b/src/react/tests/useQuery.test.tsx index 7400ebee04..5170c51c57 100644 --- a/src/react/tests/useQuery.test.tsx +++ b/src/react/tests/useQuery.test.tsx @@ -4505,4 +4505,80 @@ describe('useQuery', () => { consoleMock.mockRestore() }) + + it('should have no error in loading state when refetching after error occurred', async () => { + const consoleMock = mockConsoleError() + const key = queryKey() + const states: UseQueryResult<number>[] = [] + const error = new Error('oops') + + let count = 0 + + function Page() { + const state = useQuery( + key, + async () => { + await sleep(10) + if (count === 0) { + count++ + throw error + } + return 5 + }, + { + retry: false, + } + ) + + states.push(state) + + if (state.isLoading) { + return <div>status: loading</div> + } + if (state.error instanceof Error) { + return ( + <div> + <div>error</div> + <button onClick={() => state.refetch()}>refetch</button> + </div> + ) + } + return <div>data: {state.data}</div> + } + + const rendered = renderWithClient(queryClient, <Page />) + + await waitFor(() => rendered.getByText('error')) + + fireEvent.click(rendered.getByRole('button', { name: 'refetch' })) + await waitFor(() => rendered.getByText('data: 5')) + + await waitFor(() => expect(states.length).toBe(4)) + + expect(states[0]).toMatchObject({ + status: 'loading', + data: undefined, + error: null, + }) + + expect(states[1]).toMatchObject({ + status: 'error', + data: undefined, + error, + }) + + expect(states[2]).toMatchObject({ + status: 'loading', + data: undefined, + error: null, + }) + + expect(states[3]).toMatchObject({ + status: 'success', + data: 5, + error: null, + }) + + consoleMock.mockRestore() + }) })