blob: 492596215f082b7a189ad1eccfa19be264f78dbe [file] [log] [blame]
// Copyright 2024 The Flutter Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
import 'dart:async';
/// Runs [callback] and retries if an exception is thrown.
///
/// * [maxRetries] the maximum number of times [callback] will be ran before
/// rethrowing an exception if it does not complete successfully.
/// * [retryDelay] the time to wait between retry attempts.
/// * [stopCondition] an optional callback that determines whether we should
/// stop retrying, in addition to the condition that we must not retry
/// more than [maxRetries] times. If the [stopCondition] is met, we will stop
/// retrying without exception.
/// * [onRetry] an optional callback that will be called if [callback] fails
/// and we need to attempt a retry.
Future<void> runWithRetry({
required FutureOr<void> Function() callback,
required int maxRetries,
Duration retryDelay = const Duration(milliseconds: 250),
FutureOr<bool> Function()? stopCondition,
FutureOr<void> Function(int attempt)? onRetry,
}) async {
for (var attempt = 1;
attempt <= maxRetries && (await stopCondition?.call() != true);
attempt++) {
try {
await callback();
break;
} catch (e) {
if (attempt == maxRetries) {
rethrow;
}
await onRetry?.call(attempt);
await Future.delayed(retryDelay);
}
}
}