Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: orElse callback when retries is exhausted #213

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions retry/lib/retry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,15 @@ class RetryOptions {
/// If no [retryIf] function is given this will retry any for any [Exception]
/// thrown. To retry on an [Error], the error must be caught and _rethrown_
/// as an [Exception].
///
/// If call [fn] retrying does not satisfies [retryIf] or [attempt] is exhausted,
/// the result of invoking the [orElse] function is returned.
/// If [orElse] is omitted, the exception on retry will be thrown.
Future<T> retry<T>(
FutureOr<T> Function() fn, {
FutureOr<bool> Function(Exception)? retryIf,
FutureOr<void> Function(Exception)? onRetry,
FutureOr<T> Function(Exception)? orElse,
}) async {
var attempt = 0;
// ignore: literal_only_boolean_expressions
Expand All @@ -132,7 +137,11 @@ class RetryOptions {
} on Exception catch (e) {
if (attempt >= maxAttempts ||
(retryIf != null && !(await retryIf(e)))) {
rethrow;
if (orElse != null) {
return orElse(e);
} else {
rethrow;
}
}
if (onRetry != null) {
await onRetry(e);
Expand Down Expand Up @@ -171,6 +180,10 @@ class RetryOptions {
/// If no [retryIf] function is given this will retry any for any [Exception]
/// thrown. To retry on an [Error], the error must be caught and _rethrown_
/// as an [Exception].
///
/// If call [fn] retrying does not satisfies [retryIf] or [attempt] is exhausted,
/// the result of invoking the [orElse] function is returned.
/// If [orElse] is omitted, the exception on retry will be thrown.
Future<T> retry<T>(
FutureOr<T> Function() fn, {
Duration delayFactor = const Duration(milliseconds: 200),
Expand All @@ -179,10 +192,11 @@ Future<T> retry<T>(
int maxAttempts = 8,
FutureOr<bool> Function(Exception)? retryIf,
FutureOr<void> Function(Exception)? onRetry,
FutureOr<T> Function(Exception)? orElse,
}) =>
RetryOptions(
delayFactor: delayFactor,
randomizationFactor: randomizationFactor,
maxDelay: maxDelay,
maxAttempts: maxAttempts,
).retry(fn, retryIf: retryIf, onRetry: onRetry);
).retry(fn, retryIf: retryIf, onRetry: onRetry,orElse: orElse);
7 changes: 7 additions & 0 deletions retry/test/retry_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,12 @@ void main() {
await expectLater(f, throwsA(isException));
expect(count, equals(2));
});

test('retry when orElse is not omitted', () async {
final result = await retry(() {
throw Exception();
}, orElse: (_) => 1, maxAttempts: 2);
expect(result, 1);
});
});
}