use-swr-error.test.tsx
Overview
This file contains a comprehensive suite of unit tests for the error handling behavior of the useSWR React hook, part of the SWR data fetching library. The tests verify that useSWR correctly manages error states, retries fetching on errors, triggers appropriate lifecycle callbacks (onError, onErrorRetry, onLoadingSlow, onSuccess), respects visibility and retry conditions, and handles edge cases such as component unmounting and synchronous/asynchronous errors.
The purpose of the file is to ensure robust, predictable error handling and retry logic within useSWR—a critical aspect for resilient data fetching in React applications.
Detailed Explanations
Test Suite: describe('useSWR - error', () => { ... })
The suite groups tests around how useSWR behaves when encountering errors during data fetching.
Individual Tests
Each test uses React Testing Library and utilities to render components using useSWR and simulate various error scenarios.
Common Testing Patterns
Key Generation: Each test generates a unique cache key via createKey() to isolate SWR caches.
Fetcher Function: Simulates fetcher behavior returning errors via createResponse(new Error(...), options) optionally delayed.
Render & Query: Components are rendered with
renderWithConfigand DOM assertions use screen.getByText orscreen.findByText.Sleep & Act:
sleepis used with React’sactto wait for asynchronous state updates.State & Callback Tracking: Variables track when callbacks (e.g.,
onError,onSuccess) are triggered.
Key Tests and Their Purposes
1. should handle errors
Verifies that when the fetcher returns an error, the component renders the error message.
Shows basic error capture in
useSWR.
Usage Example:
function Page() {
const { data, error } = useSWR(key, () => createResponse(new Error('error!')))
if (error) return <div>{error.message}</div>
return <div>hello, {data}</div>
}
2. should trigger the onError event
Confirms the
onErrorcallback prop is called with the error key when a fetcher fails.
3. should trigger error retry
Tests automatic retry logic triggered by
onErrorRetry.The test increments a counter to show consecutive retries with updated error messages.
Uses
setTimeoutinsideonErrorRetryto control retry delay.
4. should stop retrying when document is not visible
Mocks
document.visibilityStateto simulate the tab becoming hidden.Ensures retries stop when the page is not visible to avoid unnecessary network requests.
5. should not retry when shouldRetryOnError is disabled
Tests that setting
shouldRetryOnError: falsedisables retry behavior.
6. should not retry when shouldRetryOnError function returns false
Similar to above but with a function returning
false, verifying conditional retry disabling.
7. should retry when shouldRetryOnError function returns true
Verifies that returning true from
shouldRetryOnErrorenables retries.
8. should trigger the onLoadingSlow and onSuccess event
Tests lifecycle events
onLoadingSlow(when loading takes longer thanloadingTimeout) andonSuccess(on successful fetch).Uses delayed fetcher to simulate slow loading.
9. should trigger limited error retries if errorRetryCount exists
Confirms that retries stop after
errorRetryCountattempts.
10. should not trigger error retries if errorRetryCount is set to 0
Ensures no retries occur if retry count is zero.
11. should not clear error during revalidating until fetcher is finished successfully
Verifies that the error state persists during revalidation unless the fetcher succeeds.
12. should reset isValidating when an error occured synchronously
Tests that
isValidatingflag resets correctly when the fetcher throws an error immediately.
13. should reset isValidating when an error occured asynchronously
Similar to above but tests async errors.
14. should dedupe onError events
Ensures only one
onErrorevent fires for multiple components subscribing to the same key (deduplication).
15. Tests about avoiding revalidation when a key is active and has errors (isLoading and isValidating cases)
Ensures no redundant revalidation occurs when an error is already active for the cache key.
16. should trigger revalidation when first hook is unmount
Confirms that when the first hook subscribing to a key unmounts, revalidation is triggered.
Skipped Tests
Tests ensuring no side effects (callbacks) fire after component unmount.
These are marked
.skipand are not currently run.
Important Implementation Details & Algorithms
Uses mocked fetcher functions returning errors wrapped in promises with optional delays to simulate network behavior.
Uses
onErrorRetrycallback to implement custom retry logic with controlled delays and retry counts.Uses document visibility API mocking (
mockVisibilityHidden) to simulate tab visibility changes affecting retry behavior.Tests deduplication of error events when multiple components share the same cache key.
Controls retry behavior via
shouldRetryOnErroroption (boolean or function).Tracks state flags like
isValidating,isLoadingto verify correct lifecycle states around errors.
Interaction with Other Parts of the System
Relies on utilities from
./utilssuch as:sleep— pauses test execution.createResponse— simulates fetcher responses, including errors.createKey— generates unique cache keys.renderWithConfig— renders React components with SWR configuration.mockVisibilityHidden— mocks document visibility state.
Tests are designed to validate the
useSWRhook behavior, which is part of the SWR core library used throughout the application for data fetching.The tests ensure that error handling logic integrated in the SWR hook functions correctly, which is foundational for robust data fetching workflows in the system.
Visual Diagram: Component Interaction Flow in Tests
This flowchart represents the primary workflow and interactions modeled in these tests. Since this is a test file focused on hook behavior, the key components are the SWR hook, fetcher functions, and lifecycle callbacks.
flowchart TD
A[Component with useSWR] --> B[useSWR Hook]
B --> C[Fetcher Function]
C -->|Returns Error| D[Error State]
D --> E{Callbacks}
E -->|onError| F[Error Callback Triggered]
E -->|onErrorRetry| G[Retry Logic Executed]
E -->|onLoadingSlow| H[Loading Slow Callback]
E -->|onSuccess| I[Success Callback]
G --> B
B --> A
style A fill:#f9f,stroke:#333,stroke-width:1px
style B fill:#bbf,stroke:#333,stroke-width:1px
style C fill:#fbf,stroke:#333,stroke-width:1px
style D fill:#f99,stroke:#333,stroke-width:1px
style E fill:#ffd,stroke:#333,stroke-width:1px
style F fill:#fcf,stroke:#333,stroke-width:1px
style G fill:#cfc,stroke:#333,stroke-width:1px
style H fill:#cff,stroke:#333,stroke-width:1px
style I fill:#cfc,stroke:#333,stroke-width:1px
Summary
File Purpose: Test suite verifying
useSWRerror handling and retry mechanisms.Functionality Tested: Error rendering, error callbacks, retry logic, visibility handling, retry limits, lifecycle events, deduplication, and state flags.
Key Techniques: Mocked fetchers, React Testing Library, state tracking, visibility mocking, event deduplication.
System Role: Validates robustness of SWR hook’s error management, crucial for reliable data fetching in the application.
Visual Model: Flowchart illustrates the error lifecycle and callback interactions within
useSWRas exercised by the tests.
This test file is essential for maintaining the integrity and resilience of the SWR hook’s error handling, ensuring that application components relying on it behave correctly under failure scenarios.