run<T> static method
Calls action until it succeeds or attempts run out, then rethrows the last error; retryIf can stop early.
Implementation
static Future<T> run<T>(
Future<T> Function() action, {
int attempts = 3,
Duration delay = const Duration(seconds: 1),
double factor = 2,
Duration maxDelay = const Duration(seconds: 30),
bool Function(Object error)? retryIf,
void Function(Object error, int attempt)? onRetry,
}) async {
Duration wait = delay;
for (int attempt = 1; ; attempt++) {
try {
return await action();
} catch (error) {
if (attempt >= attempts || (retryIf != null && !retryIf(error))) rethrow;
onRetry?.call(error, attempt);
await Future<void>.delayed(wait);
final int next = (wait.inMilliseconds * factor).round();
wait = Duration(milliseconds: min(next, maxDelay.inMilliseconds));
}
}
}