Dart capped exponential backoff retry helper

Dart
import 'dart:async';
import 'dart:math';

Future<T> retryWithBackoff<T>(
  Future<T> Function() action, {
  int maxAttempts = 5,
  Duration base = const Duration(milliseconds: 200),
  Duration cap = const Duration(seconds: 10),
}) async {
  final rand = Random();
  for (var attempt = 1;; attempt++) {
    try {
      return await action();
    } catch (e) {
      if (attempt >= maxAttempts) rethrow;
      final exp = base.inMilliseconds * (1 << (attempt - 1));
      final ms = exp + rand.nextInt((exp ~/ 2) + 1);
      await Future<void>.delayed(Duration(milliseconds: ms < cap.inMilliseconds ? ms : cap.inMilliseconds));
    }
  }
}