Defined in: async-retryer.ts:296
Provides robust retry functionality for asynchronous functions, supporting configurable backoff strategies, attempt limits, timeout controls, and detailed state management. The AsyncRetryer class is designed to help you reliably execute async operations that may fail intermittently, such as network requests or database operations, by automatically retrying them according to your chosen policy.
Retrying: Automatically re-executes a failed async function up to a specified number of attempts. Useful for handling transient errors (e.g., network flakiness, rate limits, temporary server issues).
Backoff Strategies: Controls the delay between retry attempts (default: 'exponential'):
Jitter: Adds randomness to retry delays to prevent thundering herd problems (default: 0). Set to a value between 0-1 to apply that percentage of random variation to each delay.
Max Wait: Caps the maximum wait time between retries (default: Infinity). Useful for preventing exponential backoff from growing too large (e.g., cap at 30s even if exponential would be 64s).
Timeout Controls: Set limits on execution time to prevent hanging operations:
Abort & Cancellation: Supports cancellation via an internal AbortController. Call abort() to stop retries. Use getAbortSignal() to make your async function actually cancellable (e.g., with fetch requests).
Uses TanStack Store for fine-grained reactivity. State can be accessed via the store.state property.
Available state properties:
currentAttempt: The current retry attempt number (0 when not executing)
executionCount: Total number of completed executions (successful or failed)
isExecuting: Whether the retryer is currently executing the function
lastError: The most recent error encountered during execution
lastExecutionTime: Timestamp of the last execution completion in milliseconds
lastResult: The result from the most recent successful execution
status: Current execution status ('disabled' | 'idle' | 'executing' | 'retrying')
totalExecutionTime: Total time spent executing (including retries) in milliseconds
The throwOnError option controls when errors are thrown (default: 'last'):
'last': Only throws the final error after all retries are exhausted - DEFAULT
true: Throws every error immediately (disables retrying)
false: Never throws errors, returns undefined instead
Callbacks for lifecycle management:
onAbort: Called when execution is aborted (manually or due to timeouts)
onError: Called for every error (including during retries)
onLastError: Called only for the final error after all retries fail
onRetry: Called before each retry attempt
onSettled: Called after execution completes (success or failure) of each attempt
onSuccess: Called when execution succeeds
onExecutionTimeout: Called when a single execution attempt times out
onTotalExecutionTimeout: Called when the total execution time times out
Use for async operations that may fail transiently and benefit from retrying.
Configure maxAttempts, backoff, baseWait, maxWait, and jitter to control retry behavior.
Set maxExecutionTime and maxTotalExecutionTime to prevent hanging operations.
Use onAbort, onError, onLastError, onRetry, onSettled, onSuccess, onExecutionTimeout, and onTotalExecutionTimeout for custom side effects.
Call abort() to cancel ongoing execution and pending retries.
Call reset() to reset state and cancel execution.
Use getAbortSignal() to make your async function cancellable.
Use dynamic options (functions) for maxAttempts, baseWait, and enabled based on retryer state.
Important: This class is designed for single-use execution. Calling execute() multiple times on the same instance will abort previous executions. For multiple calls, create a new instance each time.
// Retry a fetch operation up to 5 times with exponential backoff, jitter, and timeouts
const retryer = new AsyncRetryer(async (url: string) => {
const signal = retryer.getAbortSignal()
return await fetch(url, { signal })
}, {
maxAttempts: 5,
backoff: 'exponential',
baseWait: 1000,
jitter: 0.1, // Add 10% random variation to prevent thundering herd
maxExecutionTime: 5000, // Abort individual calls after 5 seconds
maxTotalExecutionTime: 30000, // Abort entire operation after 30 seconds
onRetry: (attempt, error) => console.log(`Retry attempt ${attempt} after error:`, error),
onSuccess: (result) => console.log('Success:', result),
onError: (error) => console.error('Error:', error),
onLastError: (error) => console.error('All retries failed:', error),
})
const result = await retryer.execute('/api/data')TFn extends AnyAsyncFunction
The async function type to be retried.
new AsyncRetryer<TFn>(fn, initialOptions): AsyncRetryer<TFn>;Defined in: async-retryer.ts:309
Creates a new AsyncRetryer instance
TFn
The async function to retry
AsyncRetryerOptions<TFn> = {}
Configuration options for the retryer
AsyncRetryer<TFn>
fn: TFn;Defined in: async-retryer.ts:310
The async function to retry
key: string | undefined;Defined in: async-retryer.ts:300
options: AsyncRetryerOptions<TFn> & Omit<Required<AsyncRetryerOptions<any>>,
| "initialState"
| "key"
| "onAbort"
| "onError"
| "onLastError"
| "onRetry"
| "onSettled"
| "onSuccess"
| "onExecutionTimeout"
| "onTotalExecutionTimeout">;Defined in: async-retryer.ts:301
readonly store: Store<Readonly<AsyncRetryerState<TFn>>>;Defined in: async-retryer.ts:297
abort(reason): void;Defined in: async-retryer.ts:623
Cancels the current execution and any pending retries
The reason for the abort (defaults to 'manual')
"manual" | "execution-timeout" | "total-timeout" | "new-execution"
void
execute(...args): Promise<Awaited<ReturnType<TFn>> | undefined>;Defined in: async-retryer.ts:430
Executes the function with retry logic
...Parameters<TFn>
Arguments to pass to the function
Promise<Awaited<ReturnType<TFn>> | undefined>
The function result, or undefined if disabled or all retries failed (when throwOnError is false)
The last error if throwOnError is true and all retries fail
getAbortSignal(): AbortSignal | null;Defined in: async-retryer.ts:615
Returns the current AbortSignal for the executing operation. Use this signal in your async function to make it cancellable. Returns null when not currently executing.
AbortSignal | null
const retryer = new AsyncRetryer(async (userId: string) => {
const signal = retryer.getAbortSignal()
if (signal) {
return fetch(`/api/users/${userId}`, { signal })
}
return fetch(`/api/users/${userId}`)
})
// Abort will now actually cancel the fetch
retryer.abort()reset(): void;Defined in: async-retryer.ts:643
Resets the retryer to its initial state
void
setOptions(newOptions): void;Defined in: async-retryer.ts:340
Updates the retryer options
Partial<AsyncRetryerOptions<TFn>>
Partial options to merge with existing options
void