UNPKG

@dbs-portal/core-api

Version:

HTTP client and API utilities for DBS Portal

193 lines 5.75 kB
/** * Retry strategies for different scenarios */ /** * Exponential backoff strategy */ export function exponentialBackoff(baseDelay = 1000, maxDelay = 30000, multiplier = 2) { return (retryCount) => { return Math.min(baseDelay * Math.pow(multiplier, retryCount), maxDelay); }; } /** * Linear backoff strategy */ export function linearBackoff(baseDelay = 1000, increment = 1000) { return (retryCount) => { return baseDelay + increment * retryCount; }; } /** * Fixed delay strategy */ export function fixedDelay(delay = 1000) { return () => delay; } /** * Jittered exponential backoff to avoid thundering herd */ export function jitteredExponentialBackoff(baseDelay = 1000, maxDelay = 30000, jitterFactor = 0.1) { return (retryCount) => { const exponentialDelay = Math.min(baseDelay * Math.pow(2, retryCount), maxDelay); const jitter = exponentialDelay * jitterFactor * Math.random(); return exponentialDelay + jitter; }; } /** * Retry condition for network errors only */ export function networkErrorsOnly(error) { return !error.response; // No response means network error } /** * Retry condition for server errors only */ export function serverErrorsOnly(error) { const status = error.response?.status; return status ? status >= 500 && status < 600 : false; } /** * Retry condition for specific status codes */ export function statusCodesOnly(codes) { return (error) => { const status = error.response?.status; return status ? codes.includes(status) : false; }; } /** * Retry condition for timeout errors */ export function timeoutErrorsOnly(error) { return error.code === 'TIMEOUT' || error.message.includes('timeout'); } /** * Retry condition that respects Retry-After headers */ export function respectRetryAfter(error) { if (error.response?.status === 429) { // Rate limited - check if Retry-After header is present const retryAfter = error.response.headers?.['retry-after'] || error.response.headers?.['Retry-After']; return !!retryAfter; } // Default retry logic for other errors return !error.response || (error.response.status >= 500 && error.response.status < 600); } /** * Comprehensive retry condition for production use */ export function productionRetryCondition(error) { // Don't retry client errors (4xx) except for specific cases if (error.response) { const status = error.response.status; // Retry on server errors if (status >= 500 && status < 600) { return true; } // Retry on specific client errors if (status === 408 || status === 429) { return true; } // Don't retry other client errors return false; } // Retry network errors return true; } /** * Conservative retry condition for critical operations */ export function conservativeRetryCondition(error) { // Only retry on clear network errors and 503 Service Unavailable if (!error.response) { return true; // Network error } return error.response.status === 503; } /** * Aggressive retry condition for non-critical operations */ export function aggressiveRetryCondition(error) { if (!error.response) { return true; // Network error } const status = error.response.status; // Don't retry on authentication/authorization errors if (status === 401 || status === 403) { return false; } // Don't retry on not found if (status === 404) { return false; } // Don't retry on bad request if (status === 400) { return false; } // Retry everything else return true; } /** * Creates a retry strategy that respects Retry-After headers */ export function createRetryAfterStrategy() { return { retries: 3, retryCondition: respectRetryAfter, retryDelay: (retryCount) => { // For now, just use exponential backoff // In a real implementation, you'd pass the error to access headers // Fallback to exponential backoff return exponentialBackoff()(retryCount); }, }; } /** * Creates a retry strategy for API rate limiting */ export function createRateLimitStrategy() { return { retries: 5, retryCondition: (error) => error.response?.status === 429, retryDelay: (retryCount) => { // For now, just use exponential backoff with jitter // In a real implementation, you'd pass the error to access headers // Fallback to exponential backoff with jitter return jitteredExponentialBackoff(2000, 60000)(retryCount); }, }; } /** * Creates a retry strategy for unreliable networks */ export function createUnreliableNetworkStrategy() { return { retries: 5, retryCondition: (error) => { // Retry on network errors and server errors return !error.response || (error.response.status >= 500 && error.response.status < 600); }, retryDelay: jitteredExponentialBackoff(500, 10000, 0.2), }; } /** * Creates a retry strategy for critical operations */ export function createCriticalOperationStrategy() { return { retries: 2, retryCondition: conservativeRetryCondition, retryDelay: fixedDelay(1000), }; } /** * Creates a retry strategy for background operations */ export function createBackgroundOperationStrategy() { return { retries: 10, retryCondition: aggressiveRetryCondition, retryDelay: exponentialBackoff(1000, 300000), // Up to 5 minutes }; } //# sourceMappingURL=retry-strategies.js.map