Skip to content

Commit

Permalink
feat: shouldErrorRetry accepts a function (#1816)
Browse files Browse the repository at this point in the history
  • Loading branch information
sairajchouhan committed Jan 27, 2022
1 parent bfb9edc commit 53dc100
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export interface PublicConfiguration<
revalidateOnReconnect: boolean
revalidateOnMount?: boolean
revalidateIfStale: boolean
shouldRetryOnError: boolean
shouldRetryOnError: boolean | ((err: Error) => boolean)
suspense?: boolean
fallbackData?: Data
fetcher?: Fn
Expand Down
7 changes: 6 additions & 1 deletion src/use-swr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,12 @@ export const useSWRHandler = <Data = any, Error = any>(
// deduped ones.
if (shouldStartNewRequest && isCurrentKeyMounted()) {
getConfig().onError(err, key, config)
if (config.shouldRetryOnError) {
if (
(typeof config.shouldRetryOnError === 'boolean' &&
config.shouldRetryOnError) ||
(isFunction(config.shouldRetryOnError) &&
config.shouldRetryOnError(err as Error))
) {
// When retrying, dedupe is always enabled
if (isActive()) {
// If it's active, stop. It will auto revalidate when refocusing
Expand Down
56 changes: 56 additions & 0 deletions test/use-swr-error.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,62 @@ describe('useSWR - error', () => {
screen.getByText('error: 0')
})

it('should not retry when shouldRetryOnError function returns false', async () => {
const key = createKey()
let count = 0
function Page() {
const { data, error } = useSWR(
key,
() => createResponse(new Error('error: ' + count++), { delay: 100 }),
{
onErrorRetry: (_, __, ___, revalidate, revalidateOpts) => {
revalidate(revalidateOpts)
},
dedupingInterval: 0,
shouldRetryOnError: () => false
}
)
if (error) return <div>{error.message}</div>
return <div>hello, {data}</div>
}
renderWithConfig(<Page />)
screen.getByText('hello,')

// mount
await screen.findByText('error: 0')

await act(() => sleep(150))
screen.getByText('error: 0')
})

it('should retry when shouldRetryOnError function returns true', async () => {
const key = createKey()
let count = 0
function Page() {
const { data, error } = useSWR(
key,
() => createResponse(new Error('error: ' + count++), { delay: 100 }),
{
onErrorRetry: (_, __, ___, revalidate, revalidateOpts) => {
revalidate(revalidateOpts)
},
dedupingInterval: 0,
shouldRetryOnError: () => true
}
)
if (error) return <div>{error.message}</div>
return <div>hello, {data}</div>
}
renderWithConfig(<Page />)
screen.getByText('hello,')

// mount
await screen.findByText('error: 0')

await act(() => sleep(150))
screen.getByText('error: 1')
})

it('should trigger the onLoadingSlow and onSuccess event', async () => {
const key = createKey()
let loadingSlow = null,
Expand Down

0 comments on commit 53dc100

Please sign in to comment.