Skip to content

Instantly share code, notes, and snippets.

@jotatoledo
Created February 17, 2019 15:25
Show Gist options
  • Save jotatoledo/9a14564158dc65eb3a395d0a8faed22c to your computer and use it in GitHub Desktop.
Save jotatoledo/9a14564158dc65eb3a395d0a8faed22c to your computer and use it in GitHub Desktop.
A custom operator used to retry an HTTP request
import { timer, throwError, Observable } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
export interface RetryParams {
maxAttempts?: number;
scalingDuration?: number;
shouldRetry?: ({ status: number }) => boolean;
}
const defaultParams: RetryParams = {
maxAttempts: 3,
scalingDuration: 1000,
shouldRetry: ({ status }) => status >= 400
}
/**
Examples:
http.get(...).pipe(retryWhen(genericRetryStrategy()));
See https://stackblitz.com/edit/angular-gpu41q?file=app%2Fapp.component.ts
**/
export const genericRetryStrategy = (params: RetryParams = {}) => (attempts: Observable<any>) => attempts.pipe(
mergeMap((error, i) => {
const { maxAttempts, scalingDuration, shouldRetry } = { ...defaultParams, ...params }
const retryAttempt = i + 1;
// if maximum number of retries have been met
// or response is a status code we don't wish to retry, throw error
if (retryAttempt > maxAttempts || !shouldRetry(error)) {
return throwError(error);
}
console.log(`Attempt ${retryAttempt}: retrying in ${retryAttempt * scalingDuration}ms`);
// retry after 1s, 2s, etc...
return timer(retryAttempt * scalingDuration);
})
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment