diff --git a/packages/react-query/src/__tests__/QueryResetErrorBoundary.test.tsx b/packages/react-query/src/__tests__/QueryResetErrorBoundary.test.tsx index 21d594129f..b545bbc000 100644 --- a/packages/react-query/src/__tests__/QueryResetErrorBoundary.test.tsx +++ b/packages/react-query/src/__tests__/QueryResetErrorBoundary.test.tsx @@ -294,7 +294,7 @@ describe('QueryErrorResetBoundary', () => { consoleMock.mockRestore() }) - it('should not retry fetch if the reset error boundary has not been reset', async () => { + it('should retry fetch on remount even if the reset error boundary has not been reset', async () => { const consoleMock = vi .spyOn(console, 'error') .mockImplementation(() => undefined) @@ -302,12 +302,14 @@ describe('QueryErrorResetBoundary', () => { const key = queryKey() let succeed = false + let fetchCount = 0 function Page() { const { data } = useQuery({ queryKey: key, queryFn: () => sleep(10).then(() => { + fetchCount++ if (!succeed) throw new Error('Error') return 'data' }), @@ -350,7 +352,8 @@ describe('QueryErrorResetBoundary', () => { fireEvent.click(rendered.getByText('retry')) await vi.advanceTimersByTimeAsync(11) - expect(rendered.getByText('error boundary')).toBeInTheDocument() + expect(rendered.getByText('data')).toBeInTheDocument() + expect(fetchCount).toBe(2) consoleMock.mockRestore() }) @@ -419,7 +422,7 @@ describe('QueryErrorResetBoundary', () => { consoleMock.mockRestore() }) - it('should not retry fetch if the reset error boundary has not been reset after a previous reset', async () => { + it('should retry fetch on remount if the reset error boundary has not been reset after a previous reset', async () => { const consoleMock = vi .spyOn(console, 'error') .mockImplementation(() => undefined) @@ -480,6 +483,7 @@ describe('QueryErrorResetBoundary', () => { succeed = false shouldReset = true + fireEvent.click(rendered.getByText('retry')) await vi.advanceTimersByTimeAsync(11) expect(rendered.getByText('error boundary')).toBeInTheDocument() expect(rendered.getByText('retry')).toBeInTheDocument() @@ -487,13 +491,6 @@ describe('QueryErrorResetBoundary', () => { succeed = true shouldReset = false - fireEvent.click(rendered.getByText('retry')) - await vi.advanceTimersByTimeAsync(11) - expect(rendered.getByText('error boundary')).toBeInTheDocument() - - succeed = true - shouldReset = true - fireEvent.click(rendered.getByText('retry')) await vi.advanceTimersByTimeAsync(11) expect(rendered.getByText('data')).toBeInTheDocument() diff --git a/packages/react-query/src/errorBoundaryUtils.ts b/packages/react-query/src/errorBoundaryUtils.ts index 734cc74d3d..ad9d0954bf 100644 --- a/packages/react-query/src/errorBoundaryUtils.ts +++ b/packages/react-query/src/errorBoundaryUtils.ts @@ -37,8 +37,13 @@ export const ensurePreventErrorBoundaryRetry = < options.experimental_prefetchInRender || throwOnError ) { - // Prevent retrying failed query if the error boundary has not been reset yet - if (!errorResetBoundary.isReset()) { + // Prevent retrying failed query if the error boundary has not been reset yet. + // Allow retries on a fresh mount after the error boundary has unmounted the + // failed observer. + if ( + !errorResetBoundary.isReset() && + (options.suspense || query?.getObserversCount()) + ) { options.retryOnMount = false } }