UNPKG

@gravityforms/gulp-tasks

Version:
51 lines (43 loc) 1.94 kB
/** * @description Generic async retry utility with exponential backoff. * Reads the retry count from the GITHUB_RETRY_COUNT environment variable, * falling back to a configurable default (3). * * @since 8.2.5 * * @param {Function} fn Async function to retry. * @param {Object} options Retry options. * @param {string} options.label Human-readable label for log/error messages (e.g. "push tag"). * @param {number} [options.retries] Override retry count (defaults to GITHUB_RETRY_COUNT or 3). * @param {number} [options.baseDelayMs] Base delay in ms before exponential increase (default 1000). * * @return {Promise<*>} The resolved value from the async function. */ const withRetry = async ( fn, { label, retries, baseDelayMs = 1000 } = {} ) => { const maxRetries = retries || parseInt( process.env.GITHUB_RETRY_COUNT, 10 ) || 3; let lastError; for ( let attempt = 1; attempt <= maxRetries; attempt++ ) { try { return await fn(); } catch ( error ) { lastError = error; if ( attempt < maxRetries ) { const delay = Math.pow( attempt, 2 ) * baseDelayMs; const statusInfo = error.status ? ` (${ error.status })` : ''; console.warn( `Attempt ${ attempt }/${ maxRetries } for "${ label }" failed${ statusInfo }. Retrying in ${ delay / 1000 }s...`, ); await new Promise( ( resolve ) => setTimeout( resolve, delay ) ); } } } const statusInfo = lastError.status ? ` (${ lastError.status })` : ''; const readableMessage = `${ label } failed after ${ maxRetries } attempts${ statusInfo }. ` + `The final error was: ${ lastError.message }. ` + 'This is typically caused by temporary GitHub instability — re-running the build may resolve it.'; const retryError = new Error( readableMessage ); retryError.originalError = lastError; retryError.attempts = maxRetries; throw retryError; }; export default withRetry;