Skip to content

DioEventProcessor: Append http response body #1557

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jul 26, 2023
Merged
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
[Trace origin](https://develop.sentry.dev/sdk/performance/trace-origin/) indicates what created a trace or a span. Not all transactions and spans contain enough information to tell whether the user or what precisely in the SDK created it. Origin solves this problem. The SDK now sends origin for transactions and spans.

- Add `appHangTimeoutInterval` to `SentryFlutterOptions` ([#1568](https://github.com/getsentry/sentry-dart/pull/1568))
- DioEventProcessor: Append http response body ([#1557](https://github.com/getsentry/sentry-dart/pull/1557))
- This is opt-in and depends on `maxResponseBodySize`
- Only for `dio` package

### Dependencies

Expand Down
2 changes: 2 additions & 0 deletions dart/lib/sentry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,5 @@ export 'src/utils/url_details.dart';
export 'src/utils/http_header_utils.dart';
// ignore: invalid_export_of_internal_element
export 'src/sentry_trace_origins.dart';
// ignore: invalid_export_of_internal_element
export 'src/utils.dart';
1 change: 0 additions & 1 deletion dart/lib/src/sentry_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import 'diagnostic_logger.dart';
import 'environment/environment_variables.dart';
import 'noop_client.dart';
import 'transport/noop_transport.dart';
import 'utils.dart';
import 'version.dart';

// TODO: shutdownTimeout, flushTimeoutMillis
Expand Down
5 changes: 4 additions & 1 deletion dart/lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import 'package:meta/meta.dart';

/// Sentry does not take a timezone and instead expects the date-time to be
/// submitted in UTC timezone.
@internal
DateTime getUtcDateTime() => DateTime.now().toUtc();

/// Formats a Date as ISO8601 and UTC with millis precision
@internal
String formatDateAsIso8601WithMillisPrecision(DateTime date) {
var iso = date.toIso8601String();
final millisecondSeparatorIndex = iso.lastIndexOf('.');
Expand All @@ -22,9 +24,10 @@ String formatDateAsIso8601WithMillisPrecision(DateTime date) {
return '${iso}Z';
}

@internal
final utf8JsonEncoder = JsonUtf8Encoder(null, jsonSerializationFallback, null);

@visibleForTesting
@internal
Object? jsonSerializationFallback(Object? nonEncodable) {
if (nonEncodable == null) {
return null;
Expand Down
1 change: 0 additions & 1 deletion dart/test/protocol/breadcrumb_test.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'package:collection/collection.dart';
import 'package:sentry/sentry.dart';
import 'package:test/test.dart';
import 'package:sentry/src/utils.dart';

void main() {
final timestamp = DateTime.now();
Expand Down
1 change: 0 additions & 1 deletion dart/test/sentry_envelope_header_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:sentry/sentry.dart';
import 'package:sentry/src/sentry_envelope_header.dart';
import 'package:sentry/src/utils.dart';
import 'package:test/test.dart';

import 'mocks.dart';
Expand Down
1 change: 0 additions & 1 deletion dart/test/sentry_envelope_item_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import 'package:sentry/src/sentry_envelope_item_header.dart';
import 'package:sentry/src/sentry_item_type.dart';
import 'package:sentry/src/sentry_tracer.dart';
import 'package:sentry/src/transport/data_category.dart';
import 'package:sentry/src/utils.dart';
import 'package:test/test.dart';

import 'mocks/mock_hub.dart';
Expand Down
1 change: 0 additions & 1 deletion dart/test/sentry_envelope_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'package:sentry/src/sentry_envelope_header.dart';
import 'package:sentry/src/sentry_envelope_item_header.dart';
import 'package:sentry/src/sentry_item_type.dart';
import 'package:sentry/src/sentry_tracer.dart';
import 'package:sentry/src/utils.dart';
import 'package:test/test.dart';

import 'mocks.dart';
Expand Down
1 change: 0 additions & 1 deletion dart/test/sentry_event_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import 'package:collection/collection.dart';
import 'package:sentry/sentry.dart';
import 'package:sentry/src/version.dart';
import 'package:sentry/src/utils.dart';
import 'package:test/test.dart';

void main() {
Expand Down
1 change: 0 additions & 1 deletion dart/test/sentry_span_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:sentry/sentry.dart';
import 'package:sentry/src/sentry_tracer.dart';
import 'package:sentry/src/utils.dart';
import 'package:test/test.dart';

import 'mocks/mock_hub.dart';
Expand Down
1 change: 0 additions & 1 deletion dart/test/sentry_tracer_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:sentry/sentry.dart';
import 'package:sentry/src/sentry_tracer.dart';
import 'package:sentry/src/utils.dart';
import 'package:test/test.dart';

import 'mocks.dart';
Expand Down
72 changes: 70 additions & 2 deletions dio/lib/src/dio_event_processor.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// ignore_for_file: deprecated_member_use

import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:sentry/sentry.dart';

Expand Down Expand Up @@ -62,7 +64,7 @@ class DioEventProcessor implements EventProcessor {
}

/// Returns the request data, if possible according to the users settings.
Object? _getRequestData(dynamic data) {
Object? _getRequestData(Object? data) {
if (!_options.sendDefaultPii) {
return null;
}
Expand All @@ -87,8 +89,74 @@ class DioEventProcessor implements EventProcessor {

return SentryResponse(
headers: _options.sendDefaultPii ? headers : null,
bodySize: dioError.response?.data?.length as int?,
bodySize: _getBodySize(
dioError.response?.data,
dioError.requestOptions.responseType,
),
statusCode: response?.statusCode,
data: _getResponseData(
dioError.response?.data,
dioError.requestOptions.responseType,
),
);
}

/// Returns the response data, if possible according to the users settings.
Object? _getResponseData(Object? data, ResponseType responseType) {
if (!_options.sendDefaultPii || data == null) {
return null;
}
switch (responseType) {
case ResponseType.json:
// ignore: invalid_use_of_internal_member
final jsData = utf8JsonEncoder.convert(data);
if (_options.maxResponseBodySize.shouldAddBody(jsData.length)) {
return data;
}
break;
case ResponseType.stream:
break; // No support for logging stream body.
case ResponseType.plain:
if (data is String &&
_options.maxResponseBodySize.shouldAddBody(data.codeUnits.length)) {
return data;
}
break;
case ResponseType.bytes:
if (data is List<int> &&
_options.maxResponseBodySize.shouldAddBody(data.length)) {
return data;
}
break;
}
return null;
}

int? _getBodySize(Object? data, ResponseType responseType) {
if (data == null) {
return null;
}
switch (responseType) {
case ResponseType.json:
return json.encode(data).codeUnits.length;
case ResponseType.stream:
if (data is String) {
return data.length;
} else {
return null;
}
case ResponseType.plain:
if (data is String) {
return data.codeUnits.length;
} else {
return null;
}
case ResponseType.bytes:
if (data is List<int>) {
return data.length;
} else {
return null;
}
}
}
}
Loading