executeWithRetry<T> method
Executes action with retry logic according to policy.
Returns the result on success. Throws the last exception if all attempts are exhausted.
onAttempt is called before each attempt with the 1-based attempt number.
onRetry is called before each retry delay with the attempt number and error.
delayFn is injectable for testing (avoids real waits).
Implementation
Future<T> executeWithRetry<T>(
RetryPolicy policy,
Future<T> Function() action, {
void Function(int attempt)? onAttempt,
FutureOr<void> Function(int attempt, Object error)? onRetry,
Future<void> Function(Duration delay)? delayFn,
}) async {
final effectiveDelay = delayFn ?? (Duration d) => Future<void>.delayed(d);
var attempt = 1;
while (true) {
onAttempt?.call(attempt);
try {
return await action();
} catch (e) {
if (!shouldRetry(policy, attempt)) {
rethrow;
}
await onRetry?.call(attempt, e);
final delay = calculateDelay(policy, attempt);
await effectiveDelay(delay);
attempt++;
}
}
}