execute<T> method
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');
}