/** * Retry and Circuit Breaker Utilities * * Provides retry logic with exponential backoff and circuit breaker pattern * for handling transient failures in scanner and LLM operations. * * @module util/retry */ /** * Error classification for retry decisions */ export type ErrorType = "transient" | "permanent" | "unknown"; /** * Circuit breaker state */ export type CircuitState = "closed" | "open" | "half-open"; /** * Options for retry behavior */ export interface RetryOptions { /** Maximum number of retry attempts (default: 3) */ maxAttempts?: number; /** Initial delay in ms before first retry (default: 1000) */ initialDelayMs?: number; /** Maximum delay in ms between retries (default: 30000) */ maxDelayMs?: number; /** Multiplier for exponential backoff (default: 2) */ backoffMultiplier?: number; /** Add jitter to delays to prevent thundering herd (default: true) */ jitter?: boolean; /** Timeout for each attempt in ms (optional) */ attemptTimeoutMs?: number; /** Custom error classifier (default: classifyError) */ classifyError?: (error: Error) => ErrorType; /** Callback for retry attempts */ onRetry?: (attempt: number, error: Error, delayMs: number) => void; } /** * Circuit breaker options */ export interface CircuitBreakerOptions { /** Number of failures before opening circuit (default: 5) */ failureThreshold?: number; /** Time in ms before attempting to close circuit (default: 30000) */ resetTimeoutMs?: number; /** Number of successes in half-open state to close circuit (default: 2) */ successThreshold?: number; /** Callback when circuit state changes */ onStateChange?: (from: CircuitState, to: CircuitState) => void; } /** * Classify an error as transient or permanent * * Transient errors (should retry): * - Timeout errors (ETIMEDOUT, ESOCKETTIMEDOUT) * - Rate limiting (429) * - Server errors (5xx) * - Network errors (ECONNRESET, ECONNREFUSED, ENOTFOUND) * * Permanent errors (should not retry): * - File not found (ENOENT) * - Permission denied (EACCES, EPERM) * - Invalid input (4xx except 429) * - Authentication errors (401, 403) */ export declare function classifyError(error: Error): ErrorType; /** * Retry error thrown when all attempts fail */ export declare class RetryError extends Error { readonly attempts: number; readonly lastError: Error; readonly errors: Error[]; constructor(message: string, attempts: number, lastError: Error, errors: Error[]); } /** * Circuit breaker error thrown when circuit is open */ export declare class CircuitOpenError extends Error { readonly circuitName: string; readonly openedAt: Date; readonly resetAt: Date; constructor(circuitName: string, openedAt: Date, resetAt: Date); } /** * Execute a function with retry logic * * @param fn - The async function to execute * @param options - Retry options * @returns The result of the function * @throws RetryError if all attempts fail * * @example * ```typescript * const result = await withRetry( * () => fetchData(), * { maxAttempts: 3, onRetry: (attempt, err) => console.log(`Retry ${attempt}: ${err.message}`) } * ); * ``` */ export declare function withRetry(fn: () => Promise, options?: RetryOptions): Promise; /** * Circuit breaker implementation * * States: * - CLOSED: Normal operation, requests pass through * - OPEN: Circuit tripped, requests fail fast * - HALF-OPEN: Testing if service recovered */ export declare class CircuitBreaker { private state; private failures; private successes; private lastFailureTime; private readonly name; private readonly failureThreshold; private readonly resetTimeoutMs; private readonly successThreshold; private readonly onStateChange?; constructor(name: string, options?: CircuitBreakerOptions); /** * Get the current circuit state */ getState(): CircuitState; /** * Check if the circuit allows requests */ canExecute(): boolean; /** * Execute a function through the circuit breaker * * @param fn - The async function to execute * @returns The result of the function * @throws CircuitOpenError if circuit is open */ execute(fn: () => Promise): Promise; /** * Record a successful execution */ private onSuccess; /** * Record a failed execution */ private onFailure; /** * Transition to a new state */ private transition; /** * Reset the circuit breaker */ private reset; /** * Force the circuit to a specific state (for testing) */ forceState(state: CircuitState): void; /** * Get circuit breaker stats */ getStats(): { name: string; state: CircuitState; failures: number; successes: number; lastFailureTime: Date | null; }; } /** * Execute a function with both retry and circuit breaker * * @param circuitBreaker - The circuit breaker instance * @param fn - The async function to execute * @param retryOptions - Retry options * @returns The result of the function */ export declare function withRetryAndCircuitBreaker(circuitBreaker: CircuitBreaker, fn: () => Promise, retryOptions?: RetryOptions): Promise; /** * Create a retry wrapper for a function * * @param fn - The async function to wrap * @param options - Retry options * @returns A wrapped function that retries on failure */ export declare function createRetryWrapper(fn: (...args: TArgs) => Promise, options?: RetryOptions): (...args: TArgs) => Promise; //# sourceMappingURL=retry.d.ts.map