Created
March 13, 2024 19:44
-
-
Save mcavaliere/1ad611277ad633bb41d60a247727edfb to your computer and use it in GitHub Desktop.
Retry anything function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export interface FetchWithRetriesParams<T> { | |
fn: () => Promise<T>; | |
backoffType?: 'exponential' | 'linear'; | |
maxRetries?: number; | |
retryCount?: number; | |
delayMs?: number; | |
// Allows us to define custom logic to determine if the response is successful. | |
successCondition: (response: T) => boolean; | |
// Allows us to define custom logic to determine if the response is a failure. | |
errorCondition?: (response: T) => boolean; | |
// Callback for when we've detected a custom error condition. | |
onErrorCondition?: (response: T) => any; | |
// Callback for when we've exhausted all retries. | |
onExhaustedRetries?: () => any; | |
} | |
export async function fetchWithRetries<T>({ | |
fn, | |
maxRetries = 8, | |
delayMs = 2000, | |
backoffType = 'linear', | |
retryCount = 0, | |
successCondition, | |
errorCondition, | |
onErrorCondition, | |
onExhaustedRetries = (): void => { | |
throw new Error('Max retries exceeded'); | |
}, | |
}: FetchWithRetriesParams<T>): Promise<T> { | |
if (retryCount >= maxRetries) { | |
onExhaustedRetries(); | |
return await Promise.reject(); | |
} | |
const response = await fn(); | |
if (successCondition(response as T)) { | |
return response as T; | |
} | |
if (errorCondition && errorCondition(response as T) && onErrorCondition) { | |
onErrorCondition(response); | |
} | |
return await new Promise((resolve) => { | |
setTimeout(async () => { | |
const newDelayMs = | |
backoffType === 'exponential' | |
? delayMs * Math.pow(2, retryCount) | |
: delayMs; | |
const result = await fetchWithRetries({ | |
fn, | |
retryCount: retryCount + 1, | |
maxRetries, | |
delayMs: newDelayMs, | |
successCondition, | |
onExhaustedRetries, | |
}); | |
resolve(result); | |
}, delayMs); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment