onError method
Handles errors and retries the request if appropriate.
The request is retried if:
- Retry is enabled in retryOptions
- The maximum retry count hasn't been reached
- The error is retryable (connection error or matching status code)
Implementation
@override
void onError(DioException error, ErrorInterceptorHandler handler) async {
if (!retryOptions.enabled) {
return handler.next(error);
}
final attempt = _getAttemptCount(error.requestOptions);
if (attempt >= retryOptions.maxRetries) {
return handler.next(error);
}
if (!_shouldRetry(error)) {
return handler.next(error);
}
final delay = retryOptions.getDelayForAttempt(attempt);
debugPrint(
'RetryInterceptor: Retry attempt ${attempt + 1}/${retryOptions.maxRetries} '
'after ${delay.inMilliseconds}ms for ${error.requestOptions.path}',
);
await Future.delayed(delay);
try {
final newOptions = error.requestOptions;
_setAttemptCount(newOptions, attempt + 1);
final response = await dio.request(
newOptions.path,
data: newOptions.data,
queryParameters: newOptions.queryParameters,
cancelToken: newOptions.cancelToken,
onReceiveProgress: newOptions.onReceiveProgress,
onSendProgress: newOptions.onSendProgress,
options: Options(
method: newOptions.method,
headers: newOptions.headers,
extra: newOptions.extra,
responseType: newOptions.responseType,
contentType: newOptions.contentType,
validateStatus: newOptions.validateStatus,
receiveDataWhenStatusError: newOptions.receiveDataWhenStatusError,
followRedirects: newOptions.followRedirects,
maxRedirects: newOptions.maxRedirects,
requestEncoder: newOptions.requestEncoder,
responseDecoder: newOptions.responseDecoder,
listFormat: newOptions.listFormat,
sendTimeout: newOptions.sendTimeout,
receiveTimeout: newOptions.receiveTimeout,
),
);
handler.resolve(response);
} on DioException catch (e) {
handler.next(e);
}
}