retry method

Stream<T> retry({
  1. int retryCount = 3,
  2. Duration delayFactor = const Duration(seconds: 1),
  3. bool shouldRetry(
    1. Object error
    )?,
})

Retries the stream created by this factory.

retryCount specifies the maximum number of retry attempts. delayFactor determines the base delay for exponential backoff. shouldRetry can be used to decide whether to retry for a specific error.

This safely handles single-subscription streams by creating a new stream instance for each attempt.

Implementation

Stream<T> retry({
  int retryCount = 3,
  Duration delayFactor = const Duration(seconds: 1),
  bool Function(Object error)? shouldRetry,
}) async* {
  if (retryCount < 0) {
    throw ArgumentError('retryCount must be non-negative');
  }
  if (delayFactor.inMilliseconds <= 0) {
    throw ArgumentError('delayFactor must be greater than zero');
  }

  var attempts = 0;
  while (true) {
    try {
      await for (final value in this()) {
        yield value;
      }
      break;
    } catch (error) {
      if (attempts < retryCount &&
          (shouldRetry == null || shouldRetry(error))) {
        attempts++;
        final delayMillis =
            delayFactor.inMilliseconds * pow(2, attempts - 1).toInt();
        await delayMillis.millisecondsDelay();
        continue;
      }
      rethrow;
    }
  }
}