77 lines
2.1 KiB
Dart
77 lines
2.1 KiB
Dart
import 'dart:math';
|
||
|
||
/// 重试处理器,支持指数退避策略
|
||
class RetryHandler {
|
||
static const int maxRetries = 3;
|
||
static const Duration initialDelay = Duration(seconds: 1);
|
||
static const double exponentialBase = 2.0;
|
||
|
||
/// 执行带重试的异步操作
|
||
///
|
||
/// [operation] 要执行的异步操作
|
||
/// [retryIf] 可选的条件函数,返回true时才重试
|
||
/// [maxAttempts] 最大尝试次数,默认为3次
|
||
/// [onRetry] 可选的重试回调,参数为当前尝试次数和错误
|
||
static Future<T> retry<T>({
|
||
required Future<T> Function() operation,
|
||
bool Function(dynamic error)? retryIf,
|
||
int maxAttempts = maxRetries,
|
||
void Function(int attempt, dynamic error)? onRetry,
|
||
}) async {
|
||
int attempt = 0;
|
||
dynamic lastError;
|
||
|
||
while (true) {
|
||
try {
|
||
attempt++;
|
||
return await operation();
|
||
} catch (e) {
|
||
lastError = e;
|
||
|
||
// 检查是否应该重试
|
||
if (attempt >= maxAttempts || (retryIf != null && !retryIf(e))) {
|
||
rethrow;
|
||
}
|
||
|
||
// 计算延迟时间(指数退避)
|
||
final delay = initialDelay * pow(exponentialBase, attempt - 1);
|
||
|
||
// 调用重试回调
|
||
if (onRetry != null) {
|
||
onRetry(attempt, e);
|
||
}
|
||
|
||
// 等待后重试
|
||
await Future.delayed(delay);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 判断错误是否应该重试(网络相关错误)
|
||
static bool shouldRetryOnError(dynamic error) {
|
||
// 可以根据具体错误类型判断是否应该重试
|
||
// 例如:网络超时、连接失败等应该重试
|
||
// 认证失败、参数错误等不应该重试
|
||
final errorStr = error.toString().toLowerCase();
|
||
|
||
// 应该重试的错误类型
|
||
if (errorStr.contains('timeout') ||
|
||
errorStr.contains('connection') ||
|
||
errorStr.contains('network') ||
|
||
errorStr.contains('socket')) {
|
||
return true;
|
||
}
|
||
|
||
// 不应该重试的错误类型
|
||
if (errorStr.contains('authentication') ||
|
||
errorStr.contains('unauthorized') ||
|
||
errorStr.contains('forbidden') ||
|
||
errorStr.contains('invalid')) {
|
||
return false;
|
||
}
|
||
|
||
// 默认重试
|
||
return true;
|
||
}
|
||
}
|