Skip to content

Commit

Permalink
fix(useQuery): make sure that disabled queries in error state don't t…
Browse files Browse the repository at this point in the history
…hrow (#2933)
  • Loading branch information
TkDodo committed Nov 12, 2021
1 parent 57f47e1 commit d3d7fc4
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
131 changes: 131 additions & 0 deletions src/react/tests/QueryResetErrorBoundary.test.tsx
Expand Up @@ -73,6 +73,137 @@ describe('QueryErrorResetBoundary', () => {
consoleMock.mockRestore()
})

it('should not throw error if query is disabled', async () => {
const key = queryKey()

let succeed = false
const consoleMock = mockConsoleError()

function Page() {
const { data, status } = useQuery(
key,
async () => {
await sleep(10)
if (!succeed) {
throw new Error('Error')
} else {
return 'data'
}
},
{
retry: false,
enabled: !succeed,
useErrorBoundary: true,
}
)
return (
<div>
<div>status: {status}</div>
<div>{data}</div>
</div>
)
}

const rendered = renderWithClient(
queryClient,
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<div>
<div>error boundary</div>
<button
onClick={() => {
resetErrorBoundary()
}}
>
retry
</button>
</div>
)}
>
<Page />
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
)

await waitFor(() => rendered.getByText('error boundary'))
await waitFor(() => rendered.getByText('retry'))
succeed = true
fireEvent.click(rendered.getByText('retry'))
await waitFor(() => rendered.getByText('status: error'))

consoleMock.mockRestore()
})

it('should not throw error if query is disabled, and refetch if query becomes enabled again', async () => {
const key = queryKey()

let succeed = false
const consoleMock = mockConsoleError()

function Page() {
const [enabled, setEnabled] = React.useState(false)
const { data } = useQuery(
key,
async () => {
await sleep(10)
if (!succeed) {
throw new Error('Error')
} else {
return 'data'
}
},
{
retry: false,
enabled,
useErrorBoundary: true,
}
)

React.useEffect(() => {
setEnabled(true)
}, [])

return <div>{data}</div>
}

const rendered = renderWithClient(
queryClient,
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<div>
<div>error boundary</div>
<button
onClick={() => {
resetErrorBoundary()
}}
>
retry
</button>
</div>
)}
>
<Page />
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
)

await waitFor(() => rendered.getByText('error boundary'))
await waitFor(() => rendered.getByText('retry'))
succeed = true
fireEvent.click(rendered.getByText('retry'))
await waitFor(() => rendered.getByText('data'))

consoleMock.mockRestore()
})

it('should not retry fetch if the reset error boundary has not been reset', async () => {
const key = queryKey()

Expand Down
1 change: 1 addition & 0 deletions src/react/useBaseQuery.ts
Expand Up @@ -131,6 +131,7 @@ export function useBaseQuery<
// Handle error boundary
if (
result.isError &&
defaultedOptions.enabled !== false &&
!result.isFetching &&
shouldThrowError(
defaultedOptions.suspense,
Expand Down

1 comment on commit d3d7fc4

@vercel
Copy link

@vercel vercel bot commented on d3d7fc4 Nov 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.