Blog>
Snippets

Automatic Retry with Exponential Backoff

Implement a saga that catches an error and retries the failed operation with exponential backoff, suitable for handling transient failures in web requests.
import { call, put, delay } from 'redux-saga/effects';
Imports the necessary effects from redux-saga.
function* retryWithExponentialBackoff(operation, params, maxRetries = 3) {
  let retryCount = 0;
  let error;
  while (retryCount < maxRetries) {
    try {
      const response = yield call(operation, ...params);
      return response; // On success, return the response
    } catch (err) {
      error = err;
      const delayLength = Math.pow(2, retryCount) * 1000; // Exponential backoff
      yield delay(delayLength);
      retryCount++;
    }
  }
  throw error; // Throw the last error after max retries
}
Defines a generic retry function with exponential backoff. It attempts to execute the 'operation' function with the given 'params'. If the operation fails, it retries up to 'maxRetries' times, waiting exponentially longer between each try.
function* fetchResourceSaga(params) {
  try {
    const data = yield call(retryWithExponentialBackoff, fetchResource, [params]);
    yield put({ type: 'FETCH_SUCCESS', data });
  } catch (error) {
    yield put({ type: 'FETCH_FAILURE', error });
  }
}
Defines a saga that uses the retry with exponential backoff to fetch a resource. If the operation succeeds, it dispatches a 'FETCH_SUCCESS' action with the data. Otherwise, it dispatches a 'FETCH_FAILURE' action.