send method

  1. @override
Future<StreamedResponse> send(
  1. BaseRequest request
)

Intercepts outgoing HTTP requests made using the provided client.

The interceptor captures details about the request and its corresponding response, if any, then logs this information using the Infospect system.

  • request: The outgoing HTTP request.

Returns a Future that completes with the corresponding StreamedResponse once the request completes.

Implementation

@override
Future<StreamedResponse> send(BaseRequest request) async {
  StreamedResponse? response;
  List<int>? responseBytes;
  try {
    InfospectNetworkCall httpCall = InfospectNetworkCall(request.hashCode);
    InfospectNetworkRequest httpRequest = InfospectNetworkRequest();
    dynamic requestBody = '';
    int requestSize = 0;
    final List<InfospectFormDataFile> files = [];
    final List<InfospectFormDataField> fields = [];

    if (request is Request && request.body.isNotEmpty) {
      requestBody = request.body;
      requestSize = request.bodyBytes.length;
    }

    if (request is MultipartRequest) {
      request.fields.forEach((key, value) {
        fields.add(InfospectFormDataField(key, value));
      });

      for (final entry in request.files) {
        files.add(
          InfospectFormDataFile(
            entry.filename,
            entry.contentType.toString(),
            entry.length,
          ),
        );
      }
    } else if (request is Request) {
      try {
        if (request.body.isNotEmpty) {
          requestBody = request.body;
        }
      } catch (e) {
        infospect.addLog(InfospectLog(message: 'Error in request.body'));
      }
      requestSize = request.bodyBytes.length;
    }

    httpRequest = httpRequest.copyWith(
      body: requestBody,
      size: requestSize,
      formDataFields: fields,
      formDataFiles: files,
      headers: request.headers,
      contentType: request.headers['content-type'],
      queryParameters: request.url.queryParameters,
    );

    infospect.addCall(
      httpCall.copyWith(
        request: httpRequest,
        method: request.method,
        endpoint: request.url.path,
        loading: true,
        client: client.toString(),
        server: request.url.origin,
        uri: request.url.toString(),
        secure: request.url.isScheme('https'),
      ),
    );

    response = await client.send(request).onError((e, st) async {
      InfospectNetworkResponse httpResponse =
          InfospectNetworkResponse(status: -1);

      infospect.addResponse(httpResponse, request.hashCode);
      infospect.addError(
          InfospectNetworkError(error: e, stackTrace: st), request.hashCode);

      return StreamedResponse(ByteStream.fromBytes([]), 500);
    });
    InfospectNetworkResponse httpResponse = InfospectNetworkResponse();

    if (request is Request || request is MultipartRequest) {
      dynamic responseBody = '';

      responseBytes = await response.stream.toBytes();
      try {
        responseBody = utf8.decode(responseBytes);
      } catch (e, st) {
        infospect.addLog(
          InfospectLog(
            message: 'Error while decoding response bytes',
            error: e.toString(),
            stackTrace: st,
            level: DiagnosticLevel.error,
          ),
        );
      }

      infospect.addResponse(
        httpResponse.copyWith(
          size: responseBytes.length,
          headers: response.headers,
          status: response.statusCode,
          body: responseBody,
        ),
        request.hashCode,
      );

      if (response.statusCode != 200) {
        infospect.addError(
          InfospectNetworkError(
            error: response.reasonPhrase,
            stackTrace: StackTrace.fromString(responseBody),
          ),
          request.hashCode,
        );
      }

      return StreamedResponse(
        ByteStream.fromBytes(responseBytes),
        response.statusCode,
        contentLength: response.contentLength,
        request: request,
        headers: response.headers,
        isRedirect: response.isRedirect,
        persistentConnection: response.persistentConnection,
        reasonPhrase: response.reasonPhrase,
      );
    }
    return response;
  } catch (e, st) {
    infospect.addLog(
      InfospectLog(
        message: 'Error while intercepting network all',
        error: e.toString(),
        stackTrace: st,
        level: DiagnosticLevel.error,
      ),
    );

    if (response != null) {
      return StreamedResponse(
        ByteStream.fromBytes(responseBytes ?? []),
        response.statusCode,
        contentLength: response.contentLength,
        request: request,
        headers: response.headers,
        isRedirect: response.isRedirect,
        persistentConnection: response.persistentConnection,
        reasonPhrase: response.reasonPhrase,
      );
    }
    return client.send(request);
  }
}