asyncRetry<R> function
Executes an asynchronous operation with retry logic.
Retries the tryBlock
function up to maxRetries
times if it throws an error,
with customizable delay and error handling.
Parameters:
tryBlock
: The operation to execute. Retries if it throws an error.defaultValue
: Value to return if retries are exhausted andthrowOnRetryExhaustion
isfalse
. Defaults tonull
.throwOnRetryExhaustion
: Iftrue
, rethrows the last error when retries are exhausted. Defaults tofalse
, which returnsdefaultValue
instead.maxRetries
: Maximum number of retry attempts. Defaults to3
.retryDelay
: Fixed delay between retries. Defaults to 1ms. Overridden bycomputeDelay
if provided.computeDelay
: Computes a custom delay for each retry based on the retry count.onError
: Callback to handle errors during retries. Receives:error
: The exception thrown bytryBlock
.stackTrace
: The stack trace associated with the error.retries
: The number of retry attempts already made (starting at 0). IfonError
returnsfalse
, stops retrying immediately.
Returns:
A FutureOr<R?>
with the result of tryBlock
if successful.
If retries are exhausted:
- Returns
defaultValue
ifthrowOnRetryExhaustion
isfalse
. - Rethrows the last error if
throwOnRetryExhaustion
istrue
.
Example:
// Some network request:
Future<String?> fetchData() async {
throw Exception('Network error');
}
Future<void> main() async {
var result = await asyncRetry<String?>(
() => fetchData(),
defaultValue: 'Fallback value', // Return this if retries are exhausted and throwOnRetryExhaustion is false.
maxRetries: 5, // Retry up to 5 times before giving up.
retryDelay: Duration(seconds: 2), // 2 seconds delay between retries.
throwOnRetryExhaustion: true, // Rethrow the last error if all retries fail.
onError: (error, stackTrace, retries) {
print('Attempt failed (retries: $retries): $error');
return null; // Continue retrying based on maxRetries without modifying retry behavior.
// If returns `false`, retries stop early.
// If returns `true`, retries continue even if maxRetries is exceeded.
},
);
print('Result: $result');
}
Notes:
- If
throwOnRetryExhaustion
istrue
and retries fail, the last error will be rethrown. - If
computeDelay
is provided, it overridesretryDelay
. - The
onError
callback can stop retries early by returningfalse
.
Throws:
- The last error from
tryBlock
if retries are exhausted andthrowOnRetryExhaustion
istrue
.
Implementation
FutureOr<R?> asyncRetry<R>(FutureOr<R?> Function() tryBlock,
{R? defaultValue,
bool throwOnRetryExhaustion = false,
int maxRetries = 3,
Duration? retryDelay,
Duration? Function(int retry)? computeDelay,
bool? Function(Object error, StackTrace stackTrace, int retries)?
onError}) {
if (maxRetries < 0) {
maxRetries = 0;
}
retryDelay ??= Duration(milliseconds: 1);
return _asyncRetryImpl(tryBlock, 0, maxRetries, defaultValue,
throwOnRetryExhaustion, retryDelay, computeDelay, onError);
}