Error Handling and Retry Logic
This module provides mechanisms to robustly handle errors during data fetching and to implement retry strategies within the SWR (stale-while-revalidate) data fetching paradigm. It integrates React Suspense error boundaries, manual retry interfaces, and configurable automatic retry with exponential backoff to improve resilience and user experience in asynchronous operations.
Core Concepts and Purpose
The Error Handling and Retry Logic module exists to:
Gracefully manage errors that occur during asynchronous data fetching.
Provide structured ways for UI components to respond to errors, including fallback UI rendering.
Implement automatic retry strategies with configurable parameters such as retry count limits and intervals.
Support manual retry workflows that empower users to explicitly trigger revalidation after failures.
Integrate seamlessly with React Suspense and error boundaries to unify loading, error, and retry states.
This ensures that applications remain responsive and maintain data consistency even if network or server errors occur.
How the Module Works
1. Automatic Error Retry with Exponential Backoff
The module defines a default error retry function, onErrorRetry, which is responsible for scheduling revalidation attempts after an error is encountered during data fetching.
It uses an exponential backoff strategy to increase the delay between retries, reducing load on failing endpoints.
It respects a configurable maximum retry count (
errorRetryCount) and interval (errorRetryInterval).The retry delay is randomized slightly to avoid retry storms when many clients fail simultaneously.
Excerpt from src/_internal/utils/config.ts:
const onErrorRetry = (
_: unknown,
__: string,
config: Readonly<PublicConfiguration>,
revalidate: Revalidator,
opts: Required<RevalidatorOptions>
): void => {
const maxRetryCount = config.errorRetryCount
const currentRetryCount = opts.retryCount
// Exponential backoff calculation
const timeout =
~~(
(Math.random() + 0.5) *
(1 << (currentRetryCount < 8 ? currentRetryCount : 8))
) * config.errorRetryInterval
if (!isUndefined(maxRetryCount) && currentRetryCount > maxRetryCount) {
return
}
setTimeout(revalidate, timeout, opts)
}
This function is wired into the SWR lifecycle and triggers revalidation attempts according to the retry policy.
2. React Suspense and Error Boundary Integration
Error handling is integrated into React's Suspense model by using error boundaries that catch errors thrown by SWR hooks when data fetching fails.
Components using SWR hooks with suspense enabled suspend rendering until data is available.
If fetching fails, the Suspense boundary throws an error caught by an Error Boundary.
The Error Boundary renders a fallback UI with error information and retry controls.
Example usage in e2e/site/component/manual-retry.tsx:
<ErrorBoundary
FallbackComponent={Fallback}
onReset={() => {
preloadRemote() // preload data on retry reset
}}
>
<Suspense fallback={<div>loading</div>}>
<Demo />
</Suspense>
</ErrorBoundary>
The Fallback component provides a retry button that calls resetErrorBoundary to reset the error state and allow re-rendering.
3. Manual Retry UI Workflow
In addition to automatic retries, the module supports manual retry triggered by user actions:
The retry button in the error fallback UI calls SWR's
mutatefunction to explicitly revalidate data.After mutation completes, the error boundary is reset to clear the error state and resume normal rendering.
Example from e2e/site/component/manual-retry-mutate.tsx:
<button
onClick={async () => {
await mutate(key, fetcher) // manually revalidate data
resetErrorBoundary() // clear error boundary state
}}
>
retry
</button>
This pattern provides a responsive UI that allows users to recover from transient errors by retrying on demand.
Interactions with Other Modules
Core Data Fetching (
useSWR): The retry logic hooks into the core SWR hook's lifecycle, responding to fetch errors during data retrieval.Cache and Mutation: Manual retries use the global
mutatefunction to update cached data and trigger revalidation.Preloading Utilities: On retry, preloading functions may be called to prime the cache before components attempt fetching again.
Error Boundary Components: The React error boundaries wrap Suspense-enabled SWR components to catch and display errors, coordinating with retry logic.
Configuration Management: Retry parameters like interval and max count are part of the global SWR config, allowing customization per application needs.
Design Patterns and Important Concepts
Exponential Backoff with Randomization: The retry interval doubles with each retry attempt but includes random jitter to avoid thundering herd problems.
Separation of Concerns: Automatic retry logic is decoupled from UI logic; UI components handle manual retry and error display, while the SWR core manages retry scheduling.
Suspense-Compatible Error Handling: Leveraging React's Suspense and error boundary patterns allows asynchronous errors to be handled declaratively and consistently.
Optimistic UI and Cache Synchronization: Manual retry uses
mutateto update cache and re-trigger fetching, ensuring UI stays synchronized with data state.
Visualization: Manual Retry with Suspense and Error Boundary Flow
flowchart TD
A[Component Mounts] --> B[useRemoteData Hook Fetches Data]
B -->|Fetch Succeeds| F[Render Data]
B -->|Fetch Fails| C[ErrorBoundary Catches Error]
C --> D[Fallback UI with Retry Button]
D -->|User Clicks Retry| E[Trigger SWR mutate to Revalidate]
E --> B
This flowchart illustrates the lifecycle of data fetching with error handling and manual retry:
When data fetching fails, the error boundary catches the error and displays a fallback UI.
The user can trigger a manual retry, which uses SWR's
mutateto re-fetch data.On successful retry, the component renders the updated data.
Summary of Relevant Files
src/_internal/utils/config.ts: Defines the default retry strategy functiononErrorRetry, exponential backoff calculation, and default configuration parameters controlling retry count and intervals.e2e/site/component/manual-retry.tsx: Example React component demonstrating Suspense + ErrorBoundary integration with a fallback UI having a retry button that triggers preload on reset.e2e/site/component/manual-retry-mutate.tsx: Example React component showing manual retry via SWR'smutatefunction inside the error fallback UI, with suspense and error boundary wrapping.
This module is central to ensuring resilient data fetching by combining automatic retry strategies, declarative error boundaries, and manual retry mechanisms in a cohesive and extensible approach.