Skip to content

Commit 3981f52

Browse files
authored
fix(query): set error to null when going to loading state (TanStack#3106)
to be aligned with the types, as `loading` cannot have an `error` set.
1 parent 2054f5b commit 3981f52

File tree

2 files changed

+80
-1
lines changed

2 files changed

+80
-1
lines changed

src/core/query.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,10 @@ export class Query<
584584
fetchMeta: action.meta ?? null,
585585
isFetching: true,
586586
isPaused: false,
587-
status: !state.dataUpdatedAt ? 'loading' : state.status,
587+
...(!state.dataUpdatedAt && {
588+
error: null,
589+
status: 'loading',
590+
}),
588591
}
589592
case 'success':
590593
return {

src/react/tests/useQuery.test.tsx

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4505,4 +4505,80 @@ describe('useQuery', () => {
45054505

45064506
consoleMock.mockRestore()
45074507
})
4508+
4509+
it('should have no error in loading state when refetching after error occurred', async () => {
4510+
const consoleMock = mockConsoleError()
4511+
const key = queryKey()
4512+
const states: UseQueryResult<number>[] = []
4513+
const error = new Error('oops')
4514+
4515+
let count = 0
4516+
4517+
function Page() {
4518+
const state = useQuery(
4519+
key,
4520+
async () => {
4521+
await sleep(10)
4522+
if (count === 0) {
4523+
count++
4524+
throw error
4525+
}
4526+
return 5
4527+
},
4528+
{
4529+
retry: false,
4530+
}
4531+
)
4532+
4533+
states.push(state)
4534+
4535+
if (state.isLoading) {
4536+
return <div>status: loading</div>
4537+
}
4538+
if (state.error instanceof Error) {
4539+
return (
4540+
<div>
4541+
<div>error</div>
4542+
<button onClick={() => state.refetch()}>refetch</button>
4543+
</div>
4544+
)
4545+
}
4546+
return <div>data: {state.data}</div>
4547+
}
4548+
4549+
const rendered = renderWithClient(queryClient, <Page />)
4550+
4551+
await waitFor(() => rendered.getByText('error'))
4552+
4553+
fireEvent.click(rendered.getByRole('button', { name: 'refetch' }))
4554+
await waitFor(() => rendered.getByText('data: 5'))
4555+
4556+
await waitFor(() => expect(states.length).toBe(4))
4557+
4558+
expect(states[0]).toMatchObject({
4559+
status: 'loading',
4560+
data: undefined,
4561+
error: null,
4562+
})
4563+
4564+
expect(states[1]).toMatchObject({
4565+
status: 'error',
4566+
data: undefined,
4567+
error,
4568+
})
4569+
4570+
expect(states[2]).toMatchObject({
4571+
status: 'loading',
4572+
data: undefined,
4573+
error: null,
4574+
})
4575+
4576+
expect(states[3]).toMatchObject({
4577+
status: 'success',
4578+
data: 5,
4579+
error: null,
4580+
})
4581+
4582+
consoleMock.mockRestore()
4583+
})
45084584
})

0 commit comments

Comments
 (0)