axios-retryer
Version:
TypeScript-first Axios retry library with concurrency limits, request priority, token refresh, response caching, and circuit breaker plugins.
861 lines (842 loc) • 34.6 kB
TypeScript
import { Method, AxiosError, AxiosRequestConfig, AxiosInstance } from 'axios';
/**
* manual - Requests fail immediately after the first attempt.
* Optional replay can be layered in with ManualRetryPlugin.
*
* automatic - Requests retry automatically according to the configured
* retry strategy and retry count.
* */
declare const RETRY_MODES: {
readonly AUTOMATIC: "automatic";
readonly MANUAL: "manual";
};
type RetryMode = (typeof RETRY_MODES)[keyof typeof RETRY_MODES];
declare const AXIOS_RETRYER_HTTP_METHODS: {
readonly GET: "GET";
readonly POST: "POST";
readonly PUT: "PUT";
readonly PATCH: "PATCH";
readonly DELETE: "DELETE";
readonly HEAD: "HEAD";
readonly OPTIONS: "OPTIONS";
readonly PURGE: "PURGE";
readonly LINK: "LINK";
readonly UNLINK: "UNLINK";
};
type AxiosRetryerHttpMethod = Method;
declare const AXIOS_RETRYER_REQUEST_PRIORITIES: {
readonly CRITICAL: 4;
readonly HIGHEST: 3;
readonly HIGH: 2;
readonly MEDIUM: 1;
readonly LOW: 0;
};
type AxiosRetryerRequestPriority = (typeof AXIOS_RETRYER_REQUEST_PRIORITIES)[keyof typeof AXIOS_RETRYER_REQUEST_PRIORITIES];
declare const AXIOS_RETRYER_BACKOFF_TYPES: {
readonly STATIC: 0;
readonly LINEAR: 1;
readonly EXPONENTIAL: 2;
};
type AxiosRetryerBackoffType = (typeof AXIOS_RETRYER_BACKOFF_TYPES)[keyof typeof AXIOS_RETRYER_BACKOFF_TYPES];
type AxiosRetryerStatusRange = readonly [number, number];
type AxiosRetryerRetryableStatus = number | AxiosRetryerStatusRange;
interface AxiosRetryerRequestMetadata {
/** Current retry attempt count. Managed by the library; read-only for consumers. */
readonly retryAttempt?: number;
/** Override the max retry count for this specific request. */
requestRetries?: number;
/** Override the retry mode (automatic / manual) for this specific request. */
requestMode?: RetryMode;
/** Custom request identifier for cancellation targeting. */
requestId?: string;
/**
* Stable correlation identifier propagated through retries and into all log
* entries for this request. Useful for distributed tracing.
* If omitted, defaults to `requestId`.
*/
correlationId?: string;
/** Whether the request is currently in a retry cycle. Managed by the library. */
readonly isRetrying?: boolean;
/** Override request priority for queue ordering. */
priority?: AxiosRetryerRequestPriority;
/** Request creation timestamp (ms). Managed by the library. */
readonly timestamp?: number;
/** Override the backoff strategy for this specific request. */
backoffType?: AxiosRetryerBackoffType;
/** Override the retryable status codes for this specific request. */
retryableStatuses?: readonly AxiosRetryerRetryableStatus[];
/** Extra metadata for this request. */
extra?: unknown;
}
type RetryEventArgs<TEvents extends object, K extends keyof TEvents> = NonNullable<TEvents[K]> extends (...args: infer TArgs) => unknown ? TArgs : never;
type RetryEventListener<TEvents extends object, K extends keyof TEvents> = (...args: RetryEventArgs<TEvents, K>) => void;
/**
* Terminal request error payload emitted by `onRequestError`.
*/
interface AxiosRetryerRequestErrorEvent {
/** Final Axios error object that caused request failure. */
error: AxiosError;
/** Final Axios request config that failed. */
config: AxiosRequestConfig;
/** HTTP status if available, otherwise `null` for network-level failures. */
status: number | null;
/** Request identifier if available. */
requestId?: string;
/** Total attempts performed including the initial attempt. */
attempts: number;
/** Whether the final error shape is considered retryable by the active strategy. */
retryable: boolean;
}
/**
* Queue-entry payload emitted by `onRequestQueued`.
*/
interface AxiosRetryerRequestQueuedEvent {
/** Request identifier generated or assigned by RetryManager. */
requestId: string;
/** Request config entering the queue. */
config: AxiosRequestConfig;
/** Resolved priority used for queue ordering. */
priority: AxiosRetryerRequestPriority;
/** Queue size immediately after this request was enqueued. */
queueSize: number;
}
/**
* Queue-dispatch payload emitted by `onRequestDispatched`.
*/
interface AxiosRetryerRequestDispatchedEvent {
/** Request identifier generated or assigned by RetryManager. */
requestId: string;
/** Request config dispatched from the queue. */
config: AxiosRequestConfig;
/** Resolved priority used for queue ordering. */
priority: AxiosRetryerRequestPriority;
/** Time spent waiting in the queue before dispatch (milliseconds). */
queuedForMs: number;
}
/**
* Success payload emitted by `onRequestSucceeded`.
*/
interface AxiosRetryerRequestSucceededEvent {
/** Request identifier generated or assigned by RetryManager. */
requestId?: string;
/** Final request config that succeeded. */
config: AxiosRequestConfig;
/** Final HTTP status code. */
status: number;
/** Total attempts performed including the initial attempt. */
attempts: number;
}
/**
* Core events exposed by RetryManager without any plugins attached.
*/
interface CoreRetryEvents {
/**
* Triggered when the retry process begins.
*/
onRetryProcessStarted?: () => void;
/**
* Triggered before each retry attempt.
* @param config The Axios request configuration being retried.
*/
beforeRetry?: (config: AxiosRequestConfig) => void;
/**
* Triggered after a retry attempt.
* @param config The Axios request configuration being retried.
* @param success Whether the retry was successful.
* @param error If the retry failed, the error that caused the failure.
*/
afterRetry?: (config: AxiosRequestConfig, success: boolean, error?: AxiosError) => void;
/**
* Triggered when a retry is scheduled and waiting for the specified delay.
* @param delayMs The delay in milliseconds.
* @param config The Axios request configuration.
*/
onRetryScheduled?: (delayMs: number, config: AxiosRequestConfig) => void;
/**
* Triggered for each failed retry attempt.
* @param config The failed Axios request configuration.
*/
onFailure?: (config: AxiosRequestConfig) => void;
/**
* Triggered when a request enters the queue.
*
* @param payload Queue entry metadata for this request.
*/
onRequestQueued?: (payload: AxiosRetryerRequestQueuedEvent) => void;
/**
* Triggered when a queued request is dispatched from the queue to the network layer.
*
* @param payload Dispatch metadata including queue wait duration.
*/
onRequestDispatched?: (payload: AxiosRetryerRequestDispatchedEvent) => void;
/**
* Triggered when a request succeeds (initial attempt or after retries).
*
* @param payload Success metadata for this request.
*/
onRequestSucceeded?: (payload: AxiosRetryerRequestSucceededEvent) => void;
/**
* Triggered once when a request fails terminally (all retries exhausted or no-retry terminal path).
* Unlike `onFailure`, this event is emitted only for the final failure.
*
* @param payload Terminal error context for application-level handling.
*/
onRequestError?: (payload: AxiosRetryerRequestErrorEvent) => void;
/**
* Triggered when all retries are completed.
*/
onRetryProcessFinished?: () => void;
/**
* Triggered when an in-flight retry delay timer is cancelled — either because
* the user aborted the request (`source: 'user'`) or because the system shut
* the request down (`source: 'system'`, e.g. plugin destroy, queue clear).
*/
onRetryTimerCancelled?: (payload: {
requestId: string;
source: 'user' | 'system';
}) => void;
/**
* Triggered when a request cancelled.
* @param requestId Id of the cancelled request.
*/
onRequestCancelled?: (requestId: string) => void;
/**
* Called when a request fails due to network or connection issues, meaning
* no valid server response was received (e.g., user is offline).
*
* @param request - The Axios request config that encountered a connection error.
*/
onInternetConnectionError?: (request: AxiosRequestConfig) => void;
/**
* Triggered when a blocking request (at or above `blockingPriorityThreshold`) fails terminally.
* Only fires when `blockingPriorityThreshold` is configured.
*
* @param config The Axios request config of the failed blocking request.
*/
onBlockingRequestFailed?: (config: AxiosRequestConfig) => void;
/**
* Triggered when every in-flight blocking request (at or above `blockingPriorityThreshold`)
* has **succeeded** (terminal success) and none remain in the internal blocker set.
* Not emitted when a blocker fails (`onBlockingRequestFailed`) or is cancelled.
* Only fires when `blockingPriorityThreshold` is configured.
*/
onAllBlockingRequestsResolved?: () => void;
}
type RetryManagerEvents<TPluginEvents extends object = Record<never, never>> = {
[K in keyof CoreRetryEvents | keyof TPluginEvents]: K extends keyof TPluginEvents ? K extends keyof CoreRetryEvents ? CoreRetryEvents[K] & TPluginEvents[K] : TPluginEvents[K] : K extends keyof CoreRetryEvents ? CoreRetryEvents[K] : never;
};
/**
* Represents the distribution of different error types encountered
*/
interface ErrorTypesDistribution {
/** Number of network-related errors (e.g., connection failures) */
network: number;
/** Number of 5xx server errors */
server5xx: number;
/** Number of 4xx client errors */
client4xx: number;
/** Number of canceled requests */
cancelled: number;
}
/**
* Represents metrics for a specific request priority level
*/
interface PriorityMetrics {
/** The priority level (higher numbers indicate higher priority) */
priority: number;
/** Total number of retry attempts for this priority */
total: number;
/** Number of successful retries for this priority */
successes: number;
/** Number of failed retries for this priority */
failures: number;
/** Success rate percentage for this priority (0-100) */
successRate: number;
/** Failure rate percentage for this priority (0-100) */
failureRate: number;
}
/**
* AxiosRetryer detailed metrics
* */
interface AxiosRetryerDetailedMetrics {
/** Total number of requests made through the retryer */
totalRequests: number;
/** Number of successfully completed retries */
successfulRetries: number;
/** Number of failed retry attempts */
failedRetries: number;
/** Requests that failed all retry attempts */
completelyFailedRequests: number;
/** Requests canceled before completion */
canceledRequests: number;
/** Critical priority requests that failed all retries */
completelyFailedCriticalRequests: number;
/** Distribution of error types encountered */
errorTypesDistribution: ErrorTypesDistribution;
/** Distribution of retry attempts across all requests */
retryAttemptsDistribution: Record<number, number>;
/** Count of requests by priority level */
requestCountsByPriority: Record<number, number>;
/** Average time spent in queue (seconds) */
avgQueueWait: number;
/** Average delay between retry attempts (seconds) */
avgRetryDelay: number;
/** Detailed metrics grouped by request priority */
priorityMetrics: PriorityMetrics[];
/** Timer health and accumulation metrics */
timerHealth: {
/** Number of active internal timers */
activeTimers: number;
/** Number of active retry timers */
activeRetryTimers: number;
/** Health score (0 = excellent, 100+ = potential issues) */
healthScore: number;
};
}
/**
* Interface for pluggable metrics recording.
* The core library ships with no-op metrics by default.
* Use MetricsPlugin for full metrics collection.
*/
interface MetricsRecorder {
reset(): void;
buildDetailedMetrics(timerStats: {
activeTimers: number;
activeRetryTimers: number;
}): AxiosRetryerDetailedMetrics;
emitMetricsUpdated?(): void;
}
/**
* Logger interface used by RetryManager and its collaborators.
* Supply a custom implementation via {@link RetryManagerOptions.logger}
* to redirect or suppress log output.
*/
interface Logger {
log(message: string, data?: unknown): void;
error(message: string, error?: unknown): void;
warn(message: string, data?: unknown): void;
debug(message: string, meta?: unknown): void;
}
/**
* By implementing this interface, we can write our own custom retry logic
* */
interface RetryStrategy {
/**
* Add any logic here to determine that the error is retryable
* @returns boolean
* */
getIsRetryable(error: AxiosError): boolean;
/**
* Add any logic here to determine that the request should be retried.
* @returns boolean
* */
shouldRetry(error: AxiosError, attempt: number, maxRetries: number): boolean;
/**
* Add any logic here to get the retry delay on each attempt.
* @returns number
* */
getDelay(attempt: number, maxRetries: number, backoffType?: AxiosRetryerBackoffType): number;
}
/**
* Context object passed to plugins during initialization and teardown.
* Provides the plugin-facing view of RetryManager capabilities including
* plugin-only wiring hooks that are not part of the public manager API.
*/
interface PluginContext<TPluginEvents extends object = Record<never, never>> {
/** The Axios instance managed by RetryManager. */
readonly axiosInstance: AxiosInstance;
/** Returns the configured logger. */
getLogger(): Logger;
/** Subscribe to a manager or plugin event. */
on<K extends keyof RetryManagerEvents<TPluginEvents>>(event: K, listener: RetryEventListener<RetryManagerEvents<TPluginEvents>, K>): void;
/** Unsubscribe from a manager or plugin event. */
off<K extends keyof RetryManagerEvents<TPluginEvents>>(event: K, listener: RetryEventListener<RetryManagerEvents<TPluginEvents>, K>): boolean;
/** Fire all listeners registered for this event. */
emit<K extends keyof RetryManagerEvents<TPluginEvents>>(event: K, ...args: RetryEventArgs<RetryManagerEvents<TPluginEvents>, K>): void;
/**
* Identical to `emit` — fires all listeners registered for this event.
*
* Kept for backward compatibility with existing plugins. There is no semantic
* distinction from `emit`: prefer `emit` in new code.
*/
triggerAndEmit<K extends keyof RetryManagerEvents<TPluginEvents>>(event: K, ...args: RetryEventArgs<RetryManagerEvents<TPluginEvents>, K>): void;
/** Cancel a specific in-flight or queued request by its ID. */
cancelRequest(requestId: string): void;
/** Cancel all active and queued requests. */
cancelAllRequests(): void;
/** Cancel only requests currently waiting in the queue. */
cancelQueuedRequests(): void;
/**
* Register a queue gate that must approve each request before it is dispatched.
* Used by plugins that need to block request processing under certain conditions.
*/
registerQueueGate(name: string, canProcess: (request: AxiosRequestConfig) => boolean): void;
/** Remove a previously registered queue gate. */
unregisterQueueGate(name: string): boolean;
/** Trigger a queue drain pass. Useful after a gate condition changes. */
refreshQueue(): void;
/**
* Register or unregister a metrics recorder.
* Pass `null` to detach. Used by MetricsPlugin to expose metric data to the RetryManager's getMetrics() method.
*/
registerMetricsRecorder(recorder: MetricsRecorder | null): void;
/**
* Return active timer counts.
* Used by MetricsPlugin to populate the timerHealth section of detailed metrics.
*/
getTimerStats(): {
activeTimers: number;
activeRetryTimers: number;
};
/**
* Release lifecycle tracking for a request config and mark its queue slot complete.
* Used by TokenRefreshPlugin when a tracked request is intercepted for token refresh.
*/
releaseRequestTracking(config: AxiosRequestConfig): void;
}
/**
* AxiosRetryer plugin interface that can be attached with {@link RetryManager.use} and removed with {@link RetryManager.unuse}
* */
interface RetryPlugin<TPluginEvents extends object = Record<never, never>> {
/**
* Plugin name. Should be unique
* */
name: string;
/**
* Plugin version (e.g. 1.0.0)
* */
version: string;
/**
* Phantom covariant marker for TypeScript to infer `TPluginEvents` at call sites
* such as `manager.use(plugin)`. Never set this at runtime; implementations may
* simply omit it (it is always `undefined`).
* */
readonly _events?: Readonly<TPluginEvents>;
/**
* Called when the plugin is attached and initialized.
* @param context Plugin context providing manager capabilities and plugin-only wiring hooks.
* */
initialize: (context: PluginContext<TPluginEvents>) => void;
/**
* Called before the plugin is removed.
* @param context Plugin context providing manager capabilities and plugin-only wiring hooks.
* */
onBeforeDestroyed?: (context: PluginContext<TPluginEvents>) => void;
}
interface RetryManagerOptions<TPluginEvents extends object = Record<never, never>> {
/**
* The mode of retrying requests.
* - 'automatic': Automatically retry requests that meet the retry conditions.
* - 'manual': No automatic retries; manual retries must be triggered.
*
* @default 'automatic'
*
* @example
* mode: RETRY_MODES.AUTOMATIC
* Requests will retry automatically if conditions are met.
*/
mode?: RetryMode;
/**
* The maximum number of retries for requests in 'automatic' mode.
*
* @default 3
*
* @example
* retries: 5
* Requests will retry up to 5 times if retry conditions are met.
*/
retries?: number;
/**
* Custom retry strategy implementation.
* Provide your class implementing the `RetryStrategy` interface to define custom retry logic.
*
* @example
* retryStrategy: new CustomRetryStrategy()
*/
retryStrategy?: RetryStrategy;
/**
* Custom Axios instance to use for making requests.
* If not provided, a default Axios instance is created.
*
* @example
* axiosInstance: axios.create({ baseURL: 'https://api.example.com' })
*/
axiosInstance?: AxiosInstance;
/**
* Whether to throw an error if all retry attempts fail.
* If `true`, an error is thrown after the last retry fails.
*
* @default true
*
* @example
* throwErrorOnFailedRetries: false
* Allows requests to resolve with null instead of throwing an error.
*/
throwErrorOnFailedRetries?: boolean;
/**
* Whether to throw an error if any request is canceled.
* If `true`, canceled requests will result in an error being thrown.
*
* @default true
*
* @example
* throwErrorOnCancelRequest: false
* Prevents errors when requests are canceled intentionally.
*/
throwErrorOnCancelRequest?: boolean;
/**
* Enable or disable debug mode.
* If enabled, detailed logs are printed for debugging purposes.
*
* @default false
*
* @example
* debug: true
* Logs detailed retry and request handling information.
*/
debug?: boolean;
/**
* Status codes or ranges of status codes that are considered retryable.
*
* @example
* retryableStatuses: [408, 429, [500, 599] as const]
* This allows retrying requests with status codes 408, 429, and any status code between 500 and 599 (inclusive).
*/
retryableStatuses?: readonly AxiosRetryerRetryableStatus[];
/**
* HTTP methods that are considered retryable.
*
* @example
* retryableMethods: [AXIOS_RETRYER_HTTP_METHODS.GET, AXIOS_RETRYER_HTTP_METHODS.HEAD]
* Only requests using these methods will be retried.
*/
retryableMethods?: readonly AxiosRetryerHttpMethod[];
/**
* The backoff strategy used to calculate the delay between retries.
*
* @type {AxiosRetryerBackoffType}
* @default AXIOS_RETRYER_BACKOFF_TYPES.EXPONENTIAL
*
* @example
* backoffType: AXIOS_RETRYER_BACKOFF_TYPES.EXPONENTIAL
* Delays double with each retry attempt: 1s, 2s, 4s, etc.
*/
backoffType?: AxiosRetryerBackoffType;
/**
* Maximum delay (in milliseconds) any backoff strategy may produce, before jitter.
* Caps `static`, `linear`, and `exponential` strategies to prevent runaway waits and
* to keep `setTimeout` arguments inside the safe integer range.
*
* The honored `Retry-After` header is also independently capped at 5 minutes;
* `maxBackoffDelayMs` does not affect Retry-After.
*
* @default 60000 (60 seconds)
*
* @example
* maxBackoffDelayMs: 30_000
* // Caps every backoff strategy at 30 seconds.
*/
maxBackoffDelayMs?: number;
/**
* The maximum number of requests that can be processed concurrently.
*
* @default 5
*
* @example
* maxConcurrentRequests: 10
* Allows up to 10 requests to be processed simultaneously.
*/
maxConcurrentRequests?: number;
/**
* The delay (in milliseconds) before processing each request in the queue.
* This delay applies to queued requests.
*
* @default 100
*
* @example
* queueDelay: 200
* Adds a 200ms delay between dequeued requests.
*/
queueDelay?: number;
/**
* The maximum number of requests that can be queued.
* When the queue reaches this limit, subsequent requests will be rejected with a QueueFullError.
*
* @default undefined (No limit)
*
* @example
* maxQueueSize: 100
* Limits the request queue to 100 pending requests.
*/
maxQueueSize?: number;
/**
* Custom logger implementation.
* When provided, all log output is routed through this logger instead of
* the built-in console-based logger.
*
* @default undefined (uses built-in console logger)
*
* @example
* logger: {
* log: (msg, data) => myLogger.info(msg, data),
* error: (msg, err) => myLogger.error(msg, err),
* warn: (msg, data) => myLogger.warn(msg, data),
* debug: (msg, meta) => myLogger.debug(msg, meta),
* }
*/
logger?: Logger;
/**
* When set, requests with priority at or above this threshold are treated as
* "blocking". While any blocking request is in flight, lower-priority requests
* wait in the queue until all blockers complete.
*
* Fires `onBlockingRequestFailed` when a blocking request fails terminally, and
* `onAllBlockingRequestsResolved` when all in-flight blocking requests have **succeeded**.
*
* @example
* blockingPriorityThreshold: AXIOS_RETRYER_REQUEST_PRIORITIES.CRITICAL
* // CRITICAL requests will block all lower-priority requests in the queue
*/
blockingPriorityThreshold?: AxiosRetryerRequestPriority;
/**
* When `true` and a blocking request fails terminally, all queued non-blocking
* requests are cancelled. Has no effect if `blockingPriorityThreshold` is not set.
*
* @default true
*/
cancelPendingOnDependencyFailure?: boolean;
/**
* When `true`, calling `manager.on()` after the per-event listener limit is
* reached throws an `Error` instead of logging a warning and dropping the
* registration silently. Useful in development to catch listener leaks early.
*
* @default false
*/
strictListenerLimit?: boolean;
}
declare module 'axios' {
interface AxiosRequestConfig {
/**
* Per-request options for axios-retryer.
* Use this to override priority, requestId, requestRetries, requestMode,
* backoffType, or retryableStatuses on a per-request basis.
*
* Fields marked `readonly` (retryAttempt, isRetrying, timestamp) are
* managed by the library. Setting them externally has no effect and is
* intentionally excluded from the type to prevent accidental mutation.
*/
__axiosRetryer?: AxiosRetryerRequestMetadata;
}
}
declare class RetryManager<TPluginEvents extends object = Record<never, never>> {
private readonly _axiosInstance;
private readonly mode;
private readonly retries;
private readonly throwErrorOnFailedRetries;
private readonly throwErrorOnCancelRequest;
private readonly debug;
private readonly logger;
private _metricsRecorder;
private readonly eventBus;
private readonly pluginRegistry;
private readonly requestLifecycle;
private readonly retryScheduler;
private readonly disposer;
private readonly _pluginContext;
private inRetryProgress;
private readonly retryStrategy;
private readonly requestQueue;
private requestInterceptorId;
private responseInterceptorId;
private readonly blockingPriorityThreshold;
private readonly cancelPendingOnDependencyFailure;
private readonly dependencyGatekeeper;
private readonly requestInterceptorHandler;
private readonly responseInterceptorHandler;
private readonly errorInterceptorHandler;
constructor(options?: RetryManagerOptions);
private validateOptions;
private assertPositiveIntegerOption;
private assertNonNegativeIntegerOption;
private createAxiosInstance;
private createSilentCancelConfig;
/**
* Builds a synthetic response for silently-cancelled requests.
*
* Uses HTTP 204 as a non-error status so that response interceptors registered
* downstream receive it without throwing. The real signal is the `silentlyCancelled`
* flag on `config.__axiosRetryer` — interceptors that need to distinguish this case
* should check `getRequestMetadata(config)?.silentlyCancelled`.
*/
private createSilentCancelResponse;
private setupInterceptors;
private ejectRetryerInterceptors;
private handleRetryProcessFinish;
private triggerAndEmitInternal;
emit: <K extends keyof RetryManagerEvents<TPluginEvents>>(event: K, ...args: RetryEventArgs<RetryManagerEvents<TPluginEvents>, K>) => void;
triggerAndEmit: <K extends keyof RetryManagerEvents<TPluginEvents>>(event: K, ...args: RetryEventArgs<RetryManagerEvents<TPluginEvents>, K>) => void;
use: <TAddedPluginEvents extends object>(plugin: RetryPlugin<TAddedPluginEvents>, beforeRetryerInterceptors?: boolean) => RetryManager<TPluginEvents & TAddedPluginEvents>;
unuse: (pluginName: string) => boolean;
getLogger(): Logger;
listPlugins: () => {
name: string;
version: string;
}[];
on: <K extends keyof RetryManagerEvents<TPluginEvents>>(event: K, listener: RetryEventListener<RetryManagerEvents<TPluginEvents>, K>) => RetryManager<TPluginEvents>;
off: <K extends keyof RetryManagerEvents<TPluginEvents>>(event: K, listener: RetryEventListener<RetryManagerEvents<TPluginEvents>, K>) => boolean;
get axiosInstance(): AxiosInstance;
cancelRequest: (requestId: string) => void;
cancelAllRequests: () => void;
/**
* Cancel all requests currently waiting in the queue without aborting in-progress requests.
*/
cancelQueuedRequests: () => void;
destroy: () => void;
getMetrics: () => AxiosRetryerDetailedMetrics;
resetMetrics: () => void;
private createPluginContext;
}
declare class AxiosRetryerError extends Error {
readonly code: string;
constructor(message: string, code: string);
}
declare class PluginRegistrationError extends AxiosRetryerError {
readonly pluginName?: string;
readonly pluginVersion?: string;
constructor(message: string, code: 'EPLUGIN_ALREADY_REGISTERED' | 'EINVALID_PLUGIN_VERSION', pluginName?: string, pluginVersion?: string);
}
declare class QueueClearedError extends AxiosError {
constructor(request: AxiosRequestConfig);
}
declare class QueueDestroyedError extends AxiosError {
constructor(request?: AxiosRequestConfig);
}
/**
* Error thrown when the request queue has reached its maximum capacity
* and cannot accept new requests.
*/
declare class QueueFullError extends AxiosError {
constructor(request: AxiosRequestConfig);
}
declare class QueuedRequestCanceledError extends AxiosError {
readonly requestId: string;
constructor(requestId: string, request: AxiosRequestConfig);
}
declare class RequestAbortedError extends AxiosRetryerError {
readonly requestId?: string;
constructor(requestId?: string);
}
declare class RetryerConfigError extends AxiosRetryerError {
readonly optionName?: string;
readonly optionValue?: unknown;
constructor(message: string, optionName?: string, optionValue?: unknown);
}
declare class DefaultRetryStrategy implements RetryStrategy {
private readonly retryableStatuses;
private readonly retryableMethods;
private readonly backoffType;
private readonly idempotencyHeaders;
private readonly logger?;
private readonly maxBackoffDelayMs?;
private retryableMethodsLower;
private idempotencyHeadersLower;
private defaultStatusSet;
private defaultRanges;
private readonly overrideCache;
/**
* @param retryableStatuses - List of statuses or ranges that are considered retryable.
* @param retryableMethods - List of HTTP methods that are allowed to be retried.
* @param backoffType - The backoff type used to compute delay times.
* @param idempotencyHeaders - Headers that indicate a request is idempotent.
* @param logger - Optional logger for debug information.
* @param maxBackoffDelayMs - Optional cap for backoff delays before jitter.
*/
constructor(retryableStatuses?: readonly AxiosRetryerRetryableStatus[], retryableMethods?: readonly AxiosRetryerHttpMethod[], backoffType?: AxiosRetryerBackoffType, idempotencyHeaders?: readonly string[], logger?: Logger | undefined, maxBackoffDelayMs?: number | undefined);
/**
* Checks if a given status is retryable based on provided statuses.
*
* @param status - The HTTP status code.
* @param statuses - The statuses (or ranges) to test against.
* @returns true if the status is considered retryable.
*/
private isRetryableStatus;
/**
* Returns true if the error is retryable.
*
* @param error - The Axios error.
* @returns true if the error should be retried.
*/
getIsRetryable: (error: AxiosError) => boolean;
/**
* Determines whether the request should be retried based on the error and attempt count.
*
* @param error - The Axios error.
* @param attempt - The current retry attempt.
* @param maxRetries - The maximum allowed retries.
* @returns true if the request should be retried.
*/
shouldRetry: (error: AxiosError, attempt: number, maxRetries: number) => boolean;
/**
* Computes the delay for the next retry attempt.
*
* @param attempt - The current attempt number.
* @param maxRetries - The maximum retries allowed.
* @param backoffType - Optional backoff type override.
* @returns The delay in milliseconds.
*/
getDelay: (attempt: number, maxRetries: number, backoffType?: AxiosRetryerBackoffType) => number;
}
type NoInferType<T> = [T][T extends unknown ? 0 : never];
/**
* Creates a new RetryManager instance with the given options.
* Functional alternative to using the `new RetryManager()` constructor.
*
* @param options Configuration options for the retry manager
* @returns A configured RetryManager instance
*
* @example
* ```typescript
* const retryer = createRetryer({ retries: 3, debug: true });
* retryer.axiosInstance.get('/api/data').then(response => console.log(response.data));
* ```
*/
declare function createRetryer<TPluginEvents extends object = Record<never, never>>(options?: RetryManagerOptions<NoInferType<TPluginEvents>>): RetryManager<TPluginEvents>;
/**
* Interface for creating a custom retry strategy
*/
interface RetryStrategyConfig {
/**
* Custom function to determine if an error is retryable
*/
isRetryable?: (error: AxiosError) => boolean;
/**
* Custom function to determine if a request should be retried
*/
shouldRetry?: (error: AxiosError, attempt: number, maxRetries: number) => boolean;
/**
* Custom function to calculate the delay between retry attempts
*/
getDelay?: (attempt: number, maxRetries: number, backoffType?: AxiosRetryerBackoffType) => number;
}
/**
* Creates a custom retry strategy with the given configuration.
* Functional alternative to implementing the RetryStrategy interface directly.
*
* @param config Configuration for the retry strategy
* @returns A RetryStrategy implementation
*
* @example
* ```typescript
* const customStrategy = createRetryStrategy({
* isRetryable: (error) => (error.response?.status ?? 0) >= 500,
* getDelay: (attempt) => attempt * 1000 // linear backoff
* });
*
* const retryer = createRetryer({
* retryStrategy: customStrategy
* });
* ```
*/
declare function createRetryStrategy(config?: RetryStrategyConfig): RetryStrategy;
export { AXIOS_RETRYER_BACKOFF_TYPES, AXIOS_RETRYER_HTTP_METHODS, AXIOS_RETRYER_REQUEST_PRIORITIES, AxiosRetryerError, DefaultRetryStrategy, PluginRegistrationError, QueueClearedError, QueueDestroyedError, QueueFullError, QueuedRequestCanceledError, RETRY_MODES, RequestAbortedError, RetryManager, RetryerConfigError, createRetryStrategy, createRetryer };
export type { AxiosRetryerBackoffType, AxiosRetryerDetailedMetrics, AxiosRetryerHttpMethod, AxiosRetryerRequestDispatchedEvent, AxiosRetryerRequestErrorEvent, AxiosRetryerRequestMetadata, AxiosRetryerRequestPriority, AxiosRetryerRequestQueuedEvent, AxiosRetryerRequestSucceededEvent, AxiosRetryerRetryableStatus, AxiosRetryerStatusRange, CoreRetryEvents, Logger, PluginContext, RetryEventArgs, RetryEventListener, RetryManagerEvents, RetryManagerOptions, RetryMode, RetryPlugin, RetryStrategy, RetryStrategyConfig };