onError method

  1. @override
void onError(
  1. DioException error,
  2. ErrorInterceptorHandler handler
)
override

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);
  }
}