adpa-enterprise-framework-automation
Version:
Modular, standards-compliant Node.js/TypeScript automation framework for enterprise requirements, project, and data management. Provides CLI and API for BABOK v3, PMBOK 7th Edition, and DMBOK 2.0 (in progress). Production-ready Express.js API with TypeSpe
42 lines • 1.86 kB
JavaScript
// src/utils/retry.ts
// Generic retry utility with exponential backoff and support for Retry-After
export async function withRetry(fn, maxRetries = 5, initialDelay = 1000, maxDelay = 25000, jitter = true) {
let attempt = 0;
let delay = initialDelay;
while (attempt < maxRetries) {
try {
return await fn();
}
catch (err) {
// Check for HTTP 429 or explicit retryAfter/retryDelay
const status = err.status || err.code;
if (status === 429 || status === 'TooManyRequests') {
// Prefer Retry-After header or error property
const retryAfter = (typeof err.retryAfter === 'number' && err.retryAfter > 0)
? err.retryAfter
: (typeof err.retryDelay === 'number' && err.retryDelay > 0)
? err.retryDelay
: delay;
if (typeof err.message === 'string') {
console.warn(`⚠️ Retryable error (rate limit): ${err.message}`);
}
await new Promise(res => setTimeout(res, retryAfter));
delay = Math.min(delay * 2, maxDelay); // Exponential backoff
}
else {
if (typeof err.message === 'string') {
console.warn(`⚠️ Retryable error: ${err.message}`);
}
// Add jitter to avoid thundering herd
if (jitter) {
delay = Math.floor(delay * (0.85 + Math.random() * 0.3));
}
await new Promise(res => setTimeout(res, delay));
delay = Math.min(delay * 2, maxDelay);
}
}
attempt++;
}
throw new Error(`Max retries (${maxRetries}) exceeded in withRetry`);
}
//# sourceMappingURL=retry.js.map