sendRequest method

Future<HttpResponseData> sendRequest(
  1. String url, {
  2. required String method,
  3. required Map<String, String> headers,
  4. required String body,
  5. bool dryRun = false,
})

Dispatches an HTTP request to url with retry logic and timeout.

Implementation

Future<HttpResponseData> sendRequest(
  String url, {
  required String method,
  required Map<String, String> headers,
  required String body,
  bool dryRun = false,
}) async {
  if (dryRun) {
    return const HttpResponseData(statusCode: 200, body: '{"dryRun": true}');
  }

  if (_mockHandler != null) {
    return _mockHandler!(url, method: method, headers: headers, body: body);
  }

  int attempt = 0;
  while (true) {
    attempt++;
    try {
      final client = HttpClient();
      client.connectionTimeout = timeout;

      final uri = Uri.parse(url);
      final request = await client.openUrl(method, uri).timeout(timeout);

      headers.forEach((key, value) {
        request.headers.set(key, value);
      });

      request.write(body);
      final response = await request.close().timeout(timeout);

      final responseBody =
          await response.transform(utf8.decoder).join().timeout(timeout);
      client.close();

      final res = HttpResponseData(
          statusCode: response.statusCode, body: responseBody);

      if (res.isSuccess ||
          (response.statusCode >= 400 && response.statusCode < 500)) {
        return res;
      }

      if (attempt > maxRetries) {
        return res;
      }
    } catch (e) {
      if (attempt > maxRetries) {
        return HttpResponseData(
            statusCode: 500, body: 'Error after $attempt attempts: $e');
      }
    }

    await Future<void>.delayed(Duration(milliseconds: 200 * attempt));
  }
}