From 3a085103cd4e1e834a1db14876b8d7192cf78587 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Tue, 27 Jun 2023 11:32:19 +0200 Subject: [PATCH 1/9] change explicitly handled to unhandled --- dart/lib/src/run_zoned_guarded_integration.dart | 4 ++-- dart/lib/src/sentry_isolate.dart | 5 +++-- .../lib/src/integrations/flutter_error_integration.dart | 7 ++----- .../test/integrations/flutter_error_integration_test.dart | 6 +++--- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/dart/lib/src/run_zoned_guarded_integration.dart b/dart/lib/src/run_zoned_guarded_integration.dart index ba70fc2472..623a9a5f54 100644 --- a/dart/lib/src/run_zoned_guarded_integration.dart +++ b/dart/lib/src/run_zoned_guarded_integration.dart @@ -44,8 +44,8 @@ class RunZonedGuardedIntegration extends Integration { stackTrace: stackTrace, ); - // runZonedGuarded doesn't crash the App. - final mechanism = Mechanism(type: 'runZonedGuarded', handled: true); + // runZonedGuarded doesn't crash the app, but is not handled by the user. + final mechanism = Mechanism(type: 'runZonedGuarded', handled: false); final throwableMechanism = ThrowableMechanism(mechanism, exception); final event = SentryEvent( diff --git a/dart/lib/src/sentry_isolate.dart b/dart/lib/src/sentry_isolate.dart index 898904cd27..8a6b71d48f 100644 --- a/dart/lib/src/sentry_isolate.dart +++ b/dart/lib/src/sentry_isolate.dart @@ -69,9 +69,10 @@ class SentryIsolate { stackTrace == null ? null : StackTrace.fromString(stackTrace), ); - // Isolate errors don't crash the App. - final mechanism = Mechanism(type: 'isolateError', handled: true); + // Isolate errors don't crash the app, but is not handled by the user. + final mechanism = Mechanism(type: 'isolateError', handled: false); final throwableMechanism = ThrowableMechanism(mechanism, throwable); + final event = SentryEvent( throwable: throwableMechanism, level: SentryLevel.fatal, diff --git a/flutter/lib/src/integrations/flutter_error_integration.dart b/flutter/lib/src/integrations/flutter_error_integration.dart index a9f10bcc09..03f8436bf9 100644 --- a/flutter/lib/src/integrations/flutter_error_integration.dart +++ b/flutter/lib/src/integrations/flutter_error_integration.dart @@ -54,11 +54,8 @@ class FlutterErrorIntegration implements Integration { stackTrace: errorDetails.stack, ); - // FlutterError doesn't crash the App. - final mechanism = Mechanism( - type: 'FlutterError', - handled: true, - ); + // FlutterError doesn't crash the app, but is not handled by the user. + final mechanism = Mechanism(type: 'FlutterError', handled: false); final throwableMechanism = ThrowableMechanism(mechanism, exception); var event = SentryEvent( diff --git a/flutter/test/integrations/flutter_error_integration_test.dart b/flutter/test/integrations/flutter_error_integration_test.dart index 53446caeda..43df8de278 100644 --- a/flutter/test/integrations/flutter_error_integration_test.dart +++ b/flutter/test/integrations/flutter_error_integration_test.dart @@ -70,7 +70,7 @@ void main() { final throwableMechanism = event.throwableMechanism as ThrowableMechanism; expect(throwableMechanism.mechanism.type, 'FlutterError'); - expect(throwableMechanism.mechanism.handled, true); + expect(throwableMechanism.mechanism.handled, false); expect(throwableMechanism.throwable, exception); expect(event.contexts['flutter_error_details']['library'], 'sentry'); @@ -102,7 +102,7 @@ void main() { final throwableMechanism = event.throwableMechanism as ThrowableMechanism; expect(throwableMechanism.mechanism.type, 'FlutterError'); - expect(throwableMechanism.mechanism.handled, true); + expect(throwableMechanism.mechanism.handled, false); expect(event.contexts['flutter_error_details']['library'], 'sentry'); expect(event.contexts['flutter_error_details']['context'], @@ -126,7 +126,7 @@ void main() { final throwableMechanism = event.throwableMechanism as ThrowableMechanism; expect(throwableMechanism.mechanism.type, 'FlutterError'); - expect(throwableMechanism.mechanism.handled, true); + expect(throwableMechanism.mechanism.handled, false); expect(throwableMechanism.mechanism.data['hint'], isNull); expect(event.contexts['flutter_error_details'], isNull); From 4666874522eae61883a9394c58f39834d1c14302 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Tue, 27 Jun 2023 11:36:39 +0200 Subject: [PATCH 2/9] add changlog entry --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd21c716a0..0a36cc7446 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Enhancements + +- Mark exceptions not handled by user as `handled: false` ([#1535](https://github.com/getsentry/sentry-dart/pull/1535)) + ## 7.8.0 ### Enhancements From c1e8d7ae601f568cfa84c878d5d776971c827034 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Tue, 27 Jun 2023 13:59:57 +0200 Subject: [PATCH 3/9] update changelog --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a36cc7446..54693fd6d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,11 @@ ## Unreleased -### Enhancements +### Feature - Mark exceptions not handled by user as `handled: false` ([#1535](https://github.com/getsentry/sentry-dart/pull/1535)) - + - This will affect your release health data, and is therefore considered a breaking change. + ## 7.8.0 ### Enhancements From a6cb7ab4c4f21469bc3a0811f5ca65030040e695 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Mon, 17 Jul 2023 14:13:11 +0200 Subject: [PATCH 4/9] bump sentry ios version --- flutter/ios/sentry_flutter.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flutter/ios/sentry_flutter.podspec b/flutter/ios/sentry_flutter.podspec index 21be2b3c3e..2962a98cf2 100644 --- a/flutter/ios/sentry_flutter.podspec +++ b/flutter/ios/sentry_flutter.podspec @@ -12,7 +12,7 @@ Sentry SDK for Flutter with support to native through sentry-cocoa. :tag => s.version.to_s } s.source_files = 'Classes/**/*' s.public_header_files = 'Classes/**/*.h' - s.dependency 'Sentry/HybridSDK', '8.8.0' + s.dependency 'Sentry/HybridSDK', '8.9.1' s.ios.dependency 'Flutter' s.osx.dependency 'FlutterMacOS' s.ios.deployment_target = '11.0' From 33d0587b190ef0de4ccf9e1e0f2623ffaa76cd2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20Andra=C5=A1ec?= Date: Tue, 25 Jul 2023 08:30:55 +0000 Subject: [PATCH 5/9] Add `appHangTimeoutInterval` to `SentryFlutterOptions` (#1568) Co-authored-by: Manoel Aranda Neto --- CHANGELOG.md | 2 ++ flutter/example/lib/main.dart | 1 - flutter/ios/Classes/SentryFlutterPluginApple.swift | 4 ++++ .../lib/src/integrations/native_sdk_integration.dart | 2 ++ flutter/lib/src/sentry_flutter_options.dart | 10 +++++++++- .../integrations/init_native_sdk_integration_test.dart | 5 ++++- 6 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e558039d62..152a7a9d11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ [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)) + ### Dependencies - Bump Cocoa SDK from v8.8.0 to v8.9.1 ([#1553](https://github.com/getsentry/sentry-dart/pull/1553)) diff --git a/flutter/example/lib/main.dart b/flutter/example/lib/main.dart index 9d02d1ecba..6d657a589e 100644 --- a/flutter/example/lib/main.dart +++ b/flutter/example/lib/main.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:io' show Platform; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; diff --git a/flutter/ios/Classes/SentryFlutterPluginApple.swift b/flutter/ios/Classes/SentryFlutterPluginApple.swift index 42f55d3f3b..e5ae1a6c13 100644 --- a/flutter/ios/Classes/SentryFlutterPluginApple.swift +++ b/flutter/ios/Classes/SentryFlutterPluginApple.swift @@ -384,6 +384,10 @@ public class SentryFlutterPluginApple: NSObject, FlutterPlugin { if let enableAppHangTracking = arguments["enableAppHangTracking"] as? Bool { options.enableAppHangTracking = enableAppHangTracking } + + if let appHangTimeoutIntervalMillis = arguments["appHangTimeoutIntervalMillis"] as? UInt { + options.appHangTimeoutInterval = TimeInterval(appHangTimeoutIntervalMillis) / 1000 + } } private func logLevelFrom(diagnosticLevel: String) -> SentryLevel { diff --git a/flutter/lib/src/integrations/native_sdk_integration.dart b/flutter/lib/src/integrations/native_sdk_integration.dart index 89f0c5ada2..9c4a98379e 100644 --- a/flutter/lib/src/integrations/native_sdk_integration.dart +++ b/flutter/lib/src/integrations/native_sdk_integration.dart @@ -51,6 +51,8 @@ class NativeSdkIntegration implements Integration { 'enableAppHangTracking': options.enableAppHangTracking, 'connectionTimeoutMillis': options.connectionTimeout.inMilliseconds, 'readTimeoutMillis': options.readTimeout.inMilliseconds, + 'appHangTimeoutIntervalMillis': + options.appHangTimeoutInterval.inMilliseconds, }); options.sdk.addIntegration('nativeSdkIntegration'); diff --git a/flutter/lib/src/sentry_flutter_options.dart b/flutter/lib/src/sentry_flutter_options.dart index 2f5ccd96d1..a1d7755c3c 100644 --- a/flutter/lib/src/sentry_flutter_options.dart +++ b/flutter/lib/src/sentry_flutter_options.dart @@ -195,10 +195,18 @@ class SentryFlutterOptions extends SentryOptions { bool attachViewHierarchy = false; /// When enabled, the SDK tracks when the application stops responding for a - /// specific amount of time (default 2s). + /// specific amount of time, See [appHangTimeoutInterval]. /// Only available on iOS and macOS. bool enableAppHangTracking = true; + /// The minimum amount of time an app should be unresponsive to be classified + /// as an App Hanging. The actual amount may be a little longer. Avoid using + /// values lower than 100ms, which may cause a lot of app hangs events being + /// transmitted. + /// Default to 2s. + /// Only available on iOS and macOS. + Duration appHangTimeoutInterval = Duration(seconds: 2); + /// Connection timeout. This will only be synced to the Android native SDK. Duration connectionTimeout = Duration(seconds: 5); diff --git a/flutter/test/integrations/init_native_sdk_integration_test.dart b/flutter/test/integrations/init_native_sdk_integration_test.dart index ec1e59f94f..4ed6a3d3b9 100644 --- a/flutter/test/integrations/init_native_sdk_integration_test.dart +++ b/flutter/test/integrations/init_native_sdk_integration_test.dart @@ -62,6 +62,7 @@ void main() { 'enableAppHangTracking': true, 'connectionTimeoutMillis': 5000, 'readTimeoutMillis': 5000, + 'appHangTimeoutIntervalMillis': 2000, }); }); @@ -100,7 +101,8 @@ void main() { ..captureFailedRequests = false ..enableAppHangTracking = false ..connectionTimeout = Duration(milliseconds: 9001) - ..readTimeout = Duration(milliseconds: 9002); + ..readTimeout = Duration(milliseconds: 9002) + ..appHangTimeoutInterval = Duration(milliseconds: 9003); options.sdk.addIntegration('foo'); options.sdk.addPackage('bar', '1'); @@ -143,6 +145,7 @@ void main() { 'enableAppHangTracking': false, 'connectionTimeoutMillis': 9001, 'readTimeoutMillis': 9002, + 'appHangTimeoutIntervalMillis': 9003, }); }); From 3e3389168b45dba147dea4d5fdb53697679d3758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20Andra=C5=A1ec?= Date: Wed, 26 Jul 2023 11:07:03 +0000 Subject: [PATCH 6/9] DioEventProcessor: Append http response body (#1557) Co-authored-by: Manoel Aranda Neto --- CHANGELOG.md | 3 + dart/lib/sentry.dart | 2 + dart/lib/src/sentry_options.dart | 1 - dart/lib/src/utils.dart | 5 +- dart/test/protocol/breadcrumb_test.dart | 1 - dart/test/sentry_envelope_header_test.dart | 1 - dart/test/sentry_envelope_item_test.dart | 1 - dart/test/sentry_envelope_test.dart | 1 - dart/test/sentry_event_test.dart | 1 - dart/test/sentry_span_test.dart | 1 - dart/test/sentry_tracer_test.dart | 1 - dio/lib/src/dio_event_processor.dart | 72 +++++++- dio/test/dio_event_processor_test.dart | 201 ++++++++++++++++++++- 13 files changed, 277 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 152a7a9d11..a412afb301 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/dart/lib/sentry.dart b/dart/lib/sentry.dart index f23525bfda..9d06bb7e2a 100644 --- a/dart/lib/sentry.dart +++ b/dart/lib/sentry.dart @@ -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'; diff --git a/dart/lib/src/sentry_options.dart b/dart/lib/src/sentry_options.dart index 34544076ba..55450be9dd 100644 --- a/dart/lib/src/sentry_options.dart +++ b/dart/lib/src/sentry_options.dart @@ -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 diff --git a/dart/lib/src/utils.dart b/dart/lib/src/utils.dart index f349635051..db5ca614c2 100644 --- a/dart/lib/src/utils.dart +++ b/dart/lib/src/utils.dart @@ -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('.'); @@ -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; diff --git a/dart/test/protocol/breadcrumb_test.dart b/dart/test/protocol/breadcrumb_test.dart index 4062e1b895..ddd4008d98 100644 --- a/dart/test/protocol/breadcrumb_test.dart +++ b/dart/test/protocol/breadcrumb_test.dart @@ -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(); diff --git a/dart/test/sentry_envelope_header_test.dart b/dart/test/sentry_envelope_header_test.dart index 5dff84aa87..cc10f97434 100644 --- a/dart/test/sentry_envelope_header_test.dart +++ b/dart/test/sentry_envelope_header_test.dart @@ -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'; diff --git a/dart/test/sentry_envelope_item_test.dart b/dart/test/sentry_envelope_item_test.dart index 4fe01e5a8e..673f679740 100644 --- a/dart/test/sentry_envelope_item_test.dart +++ b/dart/test/sentry_envelope_item_test.dart @@ -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'; diff --git a/dart/test/sentry_envelope_test.dart b/dart/test/sentry_envelope_test.dart index 063be42ba9..375f62846e 100644 --- a/dart/test/sentry_envelope_test.dart +++ b/dart/test/sentry_envelope_test.dart @@ -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'; diff --git a/dart/test/sentry_event_test.dart b/dart/test/sentry_event_test.dart index 58fb946110..4e661638a8 100644 --- a/dart/test/sentry_event_test.dart +++ b/dart/test/sentry_event_test.dart @@ -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() { diff --git a/dart/test/sentry_span_test.dart b/dart/test/sentry_span_test.dart index 37a81309da..e878be5cf2 100644 --- a/dart/test/sentry_span_test.dart +++ b/dart/test/sentry_span_test.dart @@ -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'; diff --git a/dart/test/sentry_tracer_test.dart b/dart/test/sentry_tracer_test.dart index f2c0bcdf7c..cb9f72fdfc 100644 --- a/dart/test/sentry_tracer_test.dart +++ b/dart/test/sentry_tracer_test.dart @@ -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'; diff --git a/dio/lib/src/dio_event_processor.dart b/dio/lib/src/dio_event_processor.dart index 0e9eedd5eb..3a9603abd1 100644 --- a/dio/lib/src/dio_event_processor.dart +++ b/dio/lib/src/dio_event_processor.dart @@ -1,5 +1,7 @@ // ignore_for_file: deprecated_member_use +import 'dart:convert'; + import 'package:dio/dio.dart'; import 'package:sentry/sentry.dart'; @@ -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; } @@ -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 && + _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) { + return data.length; + } else { + return null; + } + } + } } diff --git a/dio/test/dio_event_processor_test.dart b/dio/test/dio_event_processor_test.dart index 62520b6f44..af45d0c681 100644 --- a/dio/test/dio_event_processor_test.dart +++ b/dio/test/dio_event_processor_test.dart @@ -132,6 +132,64 @@ void main() { expect(processedEvent.request?.headers, {}); }); + + test('request body is included according to $MaxResponseBodySize', + () async { + final scenarios = [ + // never + MaxBodySizeTestConfig(MaxRequestBodySize.never, 0, false), + MaxBodySizeTestConfig(MaxRequestBodySize.never, 4001, false), + MaxBodySizeTestConfig(MaxRequestBodySize.never, 10001, false), + // always + MaxBodySizeTestConfig(MaxRequestBodySize.always, 0, true), + MaxBodySizeTestConfig(MaxRequestBodySize.always, 4001, true), + MaxBodySizeTestConfig(MaxRequestBodySize.always, 10001, true), + // small + MaxBodySizeTestConfig(MaxRequestBodySize.small, 0, true), + MaxBodySizeTestConfig(MaxRequestBodySize.small, 4000, true), + MaxBodySizeTestConfig(MaxRequestBodySize.small, 4001, false), + // medium + MaxBodySizeTestConfig(MaxRequestBodySize.medium, 0, true), + MaxBodySizeTestConfig(MaxRequestBodySize.medium, 4001, true), + MaxBodySizeTestConfig(MaxRequestBodySize.medium, 10000, true), + MaxBodySizeTestConfig(MaxRequestBodySize.medium, 10001, false), + ]; + + for (final scenario in scenarios) { + final sut = fixture.getSut( + sendDefaultPii: true, + captureFailedRequests: true, + maxRequestBodySize: scenario.maxBodySize, + ); + + final data = List.generate(scenario.contentLength, (index) => 0); + final request = requestOptions.copyWith(method: 'POST', data: data); + final throwable = Exception(); + final dioError = DioError( + requestOptions: request, + response: Response( + requestOptions: request, + statusCode: 401, + data: data, + ), + ); + final event = SentryEvent( + throwable: throwable, + exceptions: [ + fixture.sentryError(throwable), + fixture.sentryError(dioError) + ], + ); + final processedEvent = sut.apply(event) as SentryEvent; + final capturedRequest = processedEvent.request; + + expect(capturedRequest, isNotNull); + expect( + capturedRequest?.data, + scenario.shouldBeIncluded ? isNotNull : isNull, + ); + } + }); }); group('response', () { @@ -140,6 +198,7 @@ void main() { final request = requestOptions.copyWith( method: 'POST', + responseType: ResponseType.plain, ); final throwable = Exception(); final dioError = DioError( @@ -181,6 +240,7 @@ void main() { final request = requestOptions.copyWith( method: 'POST', + responseType: ResponseType.plain, ); final throwable = Exception(); final dioError = DioError( @@ -211,6 +271,121 @@ void main() { expect(processedEvent.contexts.response?.statusCode, 200); expect(processedEvent.contexts.response?.headers, {}); }); + + test('response body is included according to $MaxResponseBodySize', + () async { + final scenarios = [ + // never + MaxBodySizeTestConfig(MaxResponseBodySize.never, 0, false), + MaxBodySizeTestConfig(MaxResponseBodySize.never, 4001, false), + MaxBodySizeTestConfig(MaxResponseBodySize.never, 10001, false), + // always + MaxBodySizeTestConfig(MaxResponseBodySize.always, 0, true), + MaxBodySizeTestConfig(MaxResponseBodySize.always, 4001, true), + MaxBodySizeTestConfig(MaxResponseBodySize.always, 10001, true), + // small + MaxBodySizeTestConfig(MaxResponseBodySize.small, 0, true), + MaxBodySizeTestConfig(MaxResponseBodySize.small, 4000, true), + MaxBodySizeTestConfig(MaxResponseBodySize.small, 4001, false), + // medium + MaxBodySizeTestConfig(MaxResponseBodySize.medium, 0, true), + MaxBodySizeTestConfig(MaxResponseBodySize.medium, 4001, true), + MaxBodySizeTestConfig(MaxResponseBodySize.medium, 10000, true), + MaxBodySizeTestConfig(MaxResponseBodySize.medium, 10001, false), + ]; + + for (final scenario in scenarios) { + final sut = fixture.getSut( + sendDefaultPii: true, + captureFailedRequests: true, + maxResponseBodySize: scenario.maxBodySize, + ); + + final data = List.generate(scenario.contentLength, (index) => 0); + final request = requestOptions.copyWith( + method: 'POST', + data: data, + responseType: ResponseType.bytes, + ); + final throwable = Exception(); + final dioError = DioError( + requestOptions: request, + response: Response( + requestOptions: request, + statusCode: 401, + data: data, + ), + ); + final event = SentryEvent( + throwable: throwable, + exceptions: [ + fixture.sentryError(throwable), + fixture.sentryError(dioError) + ], + ); + final processedEvent = sut.apply(event) as SentryEvent; + final capturedResponse = processedEvent.contexts.response; + + expect(capturedResponse, isNotNull); + expect( + capturedResponse?.data, + scenario.shouldBeIncluded ? isNotNull : isNull, + ); + } + }); + + test('data supports all response body types', () async { + final dataByType = { + ResponseType.plain: ['plain'], + ResponseType.bytes: [ + [1337] + ], + ResponseType.json: [ + 9001, + null, + 'string', + true, + ['list'], + {'map-key': 'map-value'}, + ] + }; + + for (final entry in dataByType.entries) { + final responseType = entry.key; + + for (final data in entry.value) { + final request = requestOptions.copyWith( + method: 'POST', + data: data, + responseType: responseType, + ); + final throwable = Exception(); + final dioError = DioError( + requestOptions: request, + response: Response( + requestOptions: request, + statusCode: 401, + data: data, + ), + ); + + final sut = fixture.getSut(sendDefaultPii: true); + + final event = SentryEvent( + throwable: throwable, + exceptions: [ + fixture.sentryError(throwable), + fixture.sentryError(dioError) + ], + ); + final processedEvent = sut.apply(event) as SentryEvent; + final capturedResponse = processedEvent.contexts.response; + + expect(capturedResponse, isNotNull); + expect(capturedResponse?.data, data); + } + } + }); }); test('$DioEventProcessor adds chained stacktraces', () { @@ -266,12 +441,18 @@ class Fixture { // ignore: invalid_use_of_internal_member SentryExceptionFactory get exceptionFactory => options.exceptionFactory; - DioEventProcessor getSut({bool sendDefaultPii = false}) { + DioEventProcessor getSut({ + bool sendDefaultPii = false, + bool captureFailedRequests = true, + MaxRequestBodySize maxRequestBodySize = MaxRequestBodySize.always, + MaxResponseBodySize maxResponseBodySize = MaxResponseBodySize.always, + }) { return DioEventProcessor( options ..sendDefaultPii = sendDefaultPii - ..maxRequestBodySize = MaxRequestBodySize.always - ..maxResponseBodySize = MaxResponseBodySize.always, + ..captureFailedRequests = captureFailedRequests + ..maxRequestBodySize = maxRequestBodySize + ..maxResponseBodySize = maxResponseBodySize, ); } @@ -283,3 +464,17 @@ class Fixture { ); } } + +class MaxBodySizeTestConfig { + MaxBodySizeTestConfig( + this.maxBodySize, + this.contentLength, + this.shouldBeIncluded, + ); + + final T maxBodySize; + final int contentLength; + final bool shouldBeIncluded; + + Matcher get matcher => shouldBeIncluded ? isNotNull : isNull; +} From 816fdd21cfcfe6bc0d60766bf93f7888decdeb7c Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Wed, 26 Jul 2023 11:11:59 +0000 Subject: [PATCH 7/9] release: 7.9.0 --- CHANGELOG.md | 2 +- dart/lib/src/version.dart | 2 +- dart/pubspec.yaml | 2 +- dio/lib/src/version.dart | 2 +- dio/pubspec.yaml | 4 ++-- file/lib/src/version.dart | 2 +- file/pubspec.yaml | 4 ++-- flutter/example/pubspec.yaml | 2 +- flutter/lib/src/version.dart | 2 +- flutter/pubspec.yaml | 4 ++-- logging/lib/src/version.dart | 2 +- logging/pubspec.yaml | 4 ++-- sqflite/lib/src/version.dart | 2 +- sqflite/pubspec.yaml | 4 ++-- 14 files changed, 19 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a412afb301..1ff7349246 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 7.9.0 ### Features diff --git a/dart/lib/src/version.dart b/dart/lib/src/version.dart index eea097529a..6e9ff2059d 100644 --- a/dart/lib/src/version.dart +++ b/dart/lib/src/version.dart @@ -9,7 +9,7 @@ library version; /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.8.0'; +const String sdkVersion = '7.9.0'; String sdkName(bool isWeb) => isWeb ? _browserSdkName : _ioSdkName; diff --git a/dart/pubspec.yaml b/dart/pubspec.yaml index b73eaf94ac..330d6084e7 100644 --- a/dart/pubspec.yaml +++ b/dart/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry -version: 7.8.0 +version: 7.9.0 description: > A crash reporting library for Dart that sends crash reports to Sentry.io. This library supports Dart VM and Web. For Flutter consider sentry_flutter instead. diff --git a/dio/lib/src/version.dart b/dio/lib/src/version.dart index 6e137694e7..0efaa7daaa 100644 --- a/dio/lib/src/version.dart +++ b/dio/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.8.0'; +const String sdkVersion = '7.9.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_dio'; diff --git a/dio/pubspec.yaml b/dio/pubspec.yaml index 2f46b81ed4..1343b6127b 100644 --- a/dio/pubspec.yaml +++ b/dio/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_dio description: An integration which adds support for performance tracing for the Dio package. -version: 7.8.0 +version: 7.9.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -11,7 +11,7 @@ environment: dependencies: dio: ^5.0.0 - sentry: 7.8.0 + sentry: 7.9.0 dev_dependencies: meta: ^1.3.0 diff --git a/file/lib/src/version.dart b/file/lib/src/version.dart index 4f79cf0c55..5b59773228 100644 --- a/file/lib/src/version.dart +++ b/file/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.8.0'; +const String sdkVersion = '7.9.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_file'; diff --git a/file/pubspec.yaml b/file/pubspec.yaml index e585c11379..d6fcad6e27 100644 --- a/file/pubspec.yaml +++ b/file/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_file description: An integration which adds support for performance tracing for dart.io.File. -version: 7.8.0 +version: 7.9.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -10,7 +10,7 @@ environment: sdk: '>=2.19.0 <4.0.0' dependencies: - sentry: 7.8.0 + sentry: 7.9.0 meta: ^1.3.0 dev_dependencies: diff --git a/flutter/example/pubspec.yaml b/flutter/example/pubspec.yaml index 648b41dd44..7b523385d8 100644 --- a/flutter/example/pubspec.yaml +++ b/flutter/example/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_flutter_example description: Demonstrates how to use the sentry_flutter plugin. -version: 7.8.0 +version: 7.9.0 publish_to: 'none' # Remove this line if you wish to publish to pub.dev diff --git a/flutter/lib/src/version.dart b/flutter/lib/src/version.dart index 97bb83ee2e..0da840e5b1 100644 --- a/flutter/lib/src/version.dart +++ b/flutter/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.8.0'; +const String sdkVersion = '7.9.0'; /// The default SDK name reported to Sentry.io in the submitted events. const String sdkName = 'sentry.dart.flutter'; diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index 110c60a8a3..f49fb9ca53 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry_flutter -version: 7.8.0 +version: 7.9.0 description: Sentry SDK for Flutter. This package aims to support different Flutter targets by relying on the many platforms supported by Sentry with native SDKs. homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart @@ -15,7 +15,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - sentry: 7.8.0 + sentry: 7.9.0 package_info_plus: '>=1.0.0 <5.0.0' meta: ^1.3.0 diff --git a/logging/lib/src/version.dart b/logging/lib/src/version.dart index f507cad902..3905a5c4dc 100644 --- a/logging/lib/src/version.dart +++ b/logging/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.8.0'; +const String sdkVersion = '7.9.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_logging'; diff --git a/logging/pubspec.yaml b/logging/pubspec.yaml index c8150b1dce..b964b9d9fd 100644 --- a/logging/pubspec.yaml +++ b/logging/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_logging description: An integration which adds support for recording log from the logging package. -version: 7.8.0 +version: 7.9.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -11,7 +11,7 @@ environment: dependencies: logging: ^1.0.0 - sentry: 7.8.0 + sentry: 7.9.0 dev_dependencies: lints: ^2.0.0 diff --git a/sqflite/lib/src/version.dart b/sqflite/lib/src/version.dart index 328e77c6bd..67be6e3068 100644 --- a/sqflite/lib/src/version.dart +++ b/sqflite/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.8.0'; +const String sdkVersion = '7.9.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_sqflite'; diff --git a/sqflite/pubspec.yaml b/sqflite/pubspec.yaml index a04ca6344f..db60eec2a5 100644 --- a/sqflite/pubspec.yaml +++ b/sqflite/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_sqflite description: An integration which adds support for performance tracing for the sqflite package. -version: 7.8.0 +version: 7.9.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -10,7 +10,7 @@ environment: flutter: '>=3.3.0' # matching sqflite dependencies: - sentry: 7.8.0 + sentry: 7.9.0 sqflite: ^2.0.0 sqflite_common: ^2.0.0 meta: ^1.3.0 From 68857378341bd38af2cbc4048637927e19c50d05 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Wed, 26 Jul 2023 15:28:57 +0200 Subject: [PATCH 8/9] fix formatting --- .../workflows/flutter_integration_test.yml | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/.github/workflows/flutter_integration_test.yml b/.github/workflows/flutter_integration_test.yml index beb70244cd..761d2771e5 100644 --- a/.github/workflows/flutter_integration_test.yml +++ b/.github/workflows/flutter_integration_test.yml @@ -46,42 +46,42 @@ jobs: - name: flutter pub get run: flutter pub get - - name: Gradle cache - uses: gradle/gradle-build-action@v2 + - name: Gradle cache + uses: gradle/gradle-build-action@v2 - - name: AVD cache - uses: actions/cache@v3 - id: avd-cache - with: - path: | - ~/.android/avd/* - ~/.android/adb* + - name: AVD cache + uses: actions/cache@v3 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* key: avd-21 - - name: create AVD and generate snapshot for caching - if: steps.avd-cache.outputs.cache-hit != 'true' - uses: reactivecircus/android-emulator-runner@d94c3fbe4fe6a29e4a5ba47c12fb47677c73656b #pin@v2.28.0 - with: - working-directory: ./flutter/example - api-level: 21 - force-avd-creation: false - emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - disable-animations: false - arch: x86_64 - profile: Nexus 6 - script: echo "Generated AVD snapshot for caching." + - name: create AVD and generate snapshot for caching + if: steps.avd-cache.outputs.cache-hit != 'true' + uses: reactivecircus/android-emulator-runner@d94c3fbe4fe6a29e4a5ba47c12fb47677c73656b #pin@v2.28.0 + with: + working-directory: ./flutter/example + api-level: 21 + force-avd-creation: false + emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: false + arch: x86_64 + profile: Nexus 6 + script: echo "Generated AVD snapshot for caching." - - name: launch android emulator & run android integration test - uses: reactivecircus/android-emulator-runner@d94c3fbe4fe6a29e4a5ba47c12fb47677c73656b #pin@v2.28.0 - with: - working-directory: ./flutter/example - api-level: 21 - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - disable-animations: true - arch: x86_64 - profile: Nexus 6 - script: flutter test integration_test/integration_test.dart --verbose + - name: launch android emulator & run android integration test + uses: reactivecircus/android-emulator-runner@d94c3fbe4fe6a29e4a5ba47c12fb47677c73656b #pin@v2.28.0 + with: + working-directory: ./flutter/example + api-level: 21 + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + arch: x86_64 + profile: Nexus 6 + script: flutter test integration_test/integration_test.dart --verbose test-ios: runs-on: macos-13 From 53f2304b61eaefb643ff452c77a2772f2aae9c54 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Thu, 27 Jul 2023 10:03:43 +0200 Subject: [PATCH 9/9] fix --- CHANGELOG.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index edfea4139d..48ec8862bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,13 @@ # Changelog -## 7.9.0 +## 8.0.0 -### Feature +### Breaking Changes -- Mark exceptions not handled by user as `handled: false` ([#1535](https://github.com/getsentry/sentry-dart/pull/1535)) +- Mark exceptions not handled by the user as `handled: false` ([#1535](https://github.com/getsentry/sentry-dart/pull/1535)) - This will affect your release health data, and is therefore considered a breaking change. + +## 7.9.0 ### Features