execute<T> method

  1. @override
Future<HttpResponse<T>> execute<T>(
  1. HttpRequest request, {
  2. T parser(
    1. dynamic
    )?,
})
override

Execute HTTP request

Executes the given request and returns an HttpResponse. The optional parser function can be used to transform the response data.

Returns a Future that completes with an HttpResponse containing the result of the HTTP operation.

Implementation

@override
Future<HttpResponse<T>> execute<T>(
  HttpRequest request, {
  T Function(dynamic)? parser,
}) async {
  final stopwatch = Stopwatch()..start();
  int attempts = 0;

  while (attempts < request.maxRetries) {
    try {
      attempts++;

      // Create HTTP request (multipart or regular)
      final httpRequest = await _createHttpRequest(request);

      // Send request
      final streamedResponse =
          await _client.send(httpRequest).timeout(request.timeout);

      final response = await http.Response.fromStream(streamedResponse);
      stopwatch.stop();

      // Check if should retry
      if (request.retryStatusCodes.contains(response.statusCode) &&
          attempts < request.maxRetries) {
        await Future.delayed(Duration(seconds: attempts * 2));
        continue;
      }

      // Process response
      return _processResponse<T>(
          response, parser, stopwatch.elapsed, request.rethrowExceptions);
    } on SocketException {
      if (attempts >= request.maxRetries) {
        throw const NoInternetException();
      }
      await Future.delayed(Duration(seconds: attempts * 2));
    } catch (e) {
      if (e.toString().contains('TimeoutException') ||
          e.toString().contains('timeout')) {
        if (attempts >= request.maxRetries) {
          throw const RequestTimeoutException();
        }
        await Future.delayed(Duration(seconds: attempts * 2));
      } else {
        if (attempts >= request.maxRetries) {
          // If it's already a NetworkException, rethrow it as-is
          if (e is NetworkException) {
            rethrow;
          }
          throw HttpException('Request failed: $e');
        }
        await Future.delayed(Duration(seconds: attempts * 2));
      }
    }
  }

  throw const HttpException('Max retry attempts exceeded');
}