Skip to content

Commit 59ffb07

Browse files
authored
Fix: Duplicated Android Breadcrumbs with no Mechanism (#954)
1 parent 5a205e7 commit 59ffb07

File tree

4 files changed

+95
-9
lines changed

4 files changed

+95
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Maps with Key Object, Object would fail during serialization if not String, Object ([#935](https://github.com/getsentry/sentry-dart/pull/935))
88
* Breadcrumbs "Concurrent Modification" ([#948](https://github.com/getsentry/sentry-dart/pull/948))
99
* Duplicative Screen size changed breadcrumbs ([#888](https://github.com/getsentry/sentry-dart/pull/888))
10+
* Duplicated Android Breadcrumbs with no Mechanism ([#954](https://github.com/getsentry/sentry-dart/pull/954))
1011
* Fix windows native method need default result ([#943](https://github.com/getsentry/sentry-dart/pull/943))
1112

1213
### Features

dart/lib/src/sentry_client.dart

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -378,12 +378,13 @@ class SentryClient {
378378
}
379379

380380
SentryEvent _eventWithRemovedBreadcrumbsIfHandled(SentryEvent event) {
381-
final exceptions = event.exceptions ?? [];
382-
final handled = exceptions.isNotEmpty
383-
? exceptions.first.mechanism?.handled == true
384-
: false;
381+
final mechanisms =
382+
(event.exceptions ?? []).map((e) => e.mechanism).whereType<Mechanism>();
383+
final hasNoMechanism = mechanisms.isEmpty;
384+
final hasOnlyHandledMechanism =
385+
mechanisms.every((e) => (e.handled ?? true));
385386

386-
if (handled) {
387+
if (hasNoMechanism || hasOnlyHandledMechanism) {
387388
return event.copyWith(breadcrumbs: []);
388389
} else {
389390
return event;

dart/test/mocks/mock_platform.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ class MockPlatform extends Platform with NoSuchMethodProvider {
99
return MockPlatform(os: 'android');
1010
}
1111

12-
@override
13-
String operatingSystem;
12+
factory MockPlatform.iOS() {
13+
return MockPlatform(os: 'ios');
14+
}
1415

1516
@override
16-
bool get isAndroid => (operatingSystem == 'android');
17+
String operatingSystem;
1718
}

dart/test/sentry_client_test.dart

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,52 @@ void main() {
898898
expect((capturedEvent.breadcrumbs ?? []).isEmpty, true);
899899
});
900900

901+
test('Clears breadcrumbs on Android if mechanism.handled is null',
902+
() async {
903+
fixture.options.enableScopeSync = true;
904+
fixture.options.platformChecker =
905+
MockPlatformChecker(platform: MockPlatform.android());
906+
907+
final client = fixture.getSut();
908+
final event = SentryEvent(exceptions: [
909+
SentryException(
910+
type: "type",
911+
value: "value",
912+
mechanism: Mechanism(type: 'type'),
913+
)
914+
], breadcrumbs: [
915+
Breadcrumb()
916+
]);
917+
await client.captureEvent(event);
918+
919+
final capturedEnvelope = (fixture.transport).envelopes.first;
920+
final capturedEvent = await eventFromEnvelope(capturedEnvelope);
921+
922+
expect((capturedEvent.breadcrumbs ?? []).isEmpty, true);
923+
});
924+
925+
test('Clears breadcrumbs on Android if theres no mechanism', () async {
926+
fixture.options.enableScopeSync = true;
927+
fixture.options.platformChecker =
928+
MockPlatformChecker(platform: MockPlatform.android());
929+
930+
final client = fixture.getSut();
931+
final event = SentryEvent(exceptions: [
932+
SentryException(
933+
type: "type",
934+
value: "value",
935+
)
936+
], breadcrumbs: [
937+
Breadcrumb()
938+
]);
939+
await client.captureEvent(event);
940+
941+
final capturedEnvelope = (fixture.transport).envelopes.first;
942+
final capturedEvent = await eventFromEnvelope(capturedEnvelope);
943+
944+
expect((capturedEvent.breadcrumbs ?? []).isEmpty, true);
945+
});
946+
901947
test('Does not clear breadcrumbs on Android if mechanism.handled is false',
902948
() async {
903949
fixture.options.enableScopeSync = true;
@@ -924,6 +970,42 @@ void main() {
924970

925971
expect((capturedEvent.breadcrumbs ?? []).isNotEmpty, true);
926972
});
973+
974+
test(
975+
'Does not clear breadcrumbs on Android if any mechanism.handled is false',
976+
() async {
977+
fixture.options.enableScopeSync = true;
978+
fixture.options.platformChecker =
979+
MockPlatformChecker(platform: MockPlatform.android());
980+
981+
final client = fixture.getSut();
982+
final event = SentryEvent(exceptions: [
983+
SentryException(
984+
type: "type",
985+
value: "value",
986+
mechanism: Mechanism(
987+
type: 'type',
988+
handled: true,
989+
),
990+
),
991+
SentryException(
992+
type: "type",
993+
value: "value",
994+
mechanism: Mechanism(
995+
type: 'type',
996+
handled: false,
997+
),
998+
)
999+
], breadcrumbs: [
1000+
Breadcrumb()
1001+
]);
1002+
await client.captureEvent(event);
1003+
1004+
final capturedEnvelope = (fixture.transport).envelopes.first;
1005+
final capturedEvent = await eventFromEnvelope(capturedEnvelope);
1006+
1007+
expect((capturedEvent.breadcrumbs ?? []).isNotEmpty, true);
1008+
});
9271009
});
9281010

9291011
group('ClientReportRecorder', () {
@@ -1118,7 +1200,8 @@ class Fixture {
11181200
final recorder = MockClientReportRecorder();
11191201
final transport = MockTransport();
11201202

1121-
final options = SentryOptions(dsn: fakeDsn);
1203+
final options = SentryOptions(dsn: fakeDsn)
1204+
..platformChecker = MockPlatformChecker(platform: MockPlatform.iOS());
11221205

11231206
late SentryTransactionContext _context;
11241207
late SentryTracer tracer;

0 commit comments

Comments
 (0)