From 69e55ceb7d392b36823fef0b6fcd0a7ee57fc883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Mon, 5 Feb 2024 19:28:18 +0100 Subject: [PATCH 1/6] Exception aggregate --- dart/lib/src/protocol/mechanism.dart | 52 ++++++++++++++++++++++++++ dart/test/protocol/mechanism_test.dart | 17 +++++++++ 2 files changed, 69 insertions(+) diff --git a/dart/lib/src/protocol/mechanism.dart b/dart/lib/src/protocol/mechanism.dart index 2c06c954f6..90bfe2cfeb 100644 --- a/dart/lib/src/protocol/mechanism.dart +++ b/dart/lib/src/protocol/mechanism.dart @@ -44,6 +44,38 @@ class Mechanism { /// This may be because they are created at a central place (like a crash handler), and are all called the same: Error, Segfault etc. When the flag is set, Sentry will then try to use other information (top in-app frame function) rather than exception type and value in the UI for the primary event display. This flag should be set for all "segfaults" for instance as every single error group would look very similar otherwise. final bool? synthetic; + /// An optional boolean value, set `true` when the exception is the exception + /// group type specific to the platform or language. + /// The default is false when omitted. + /// For example, exceptions of type (PlatformException)[https://api.flutter.dev/flutter/services/PlatformException-class.html] + /// have set it to `true`, others are set to `false`. + final bool? isExceptionGroup; + + /// An optional string value describing the source of the exception. + /// + /// The SDK should populate this with the name of the property or attribute of + /// the parent exception that this exception was acquired from. + /// In the case of an array, it should include the zero-based array index as + /// well. + final String? source; + + /// An optional numeric value providing an ID for the exception relative to + /// this specific event. + /// + /// The SDK should assign simple incrementing integers to each exception in + /// the tree, starting with 0 for the root of the tree. + /// In other words, when flattened into the list provided in the exception + /// values on the event, the last exception in the list should have ID 0, + /// the previous one should have ID 1, the next previous should have ID 2, etc. + final int? exceptionId; + + /// An optional numeric value pointing at the [exceptionId] that is the parent + /// of this exception. + /// + /// The SDK should assign this to all exceptions except the root exception + /// (the last to be listed in the exception values). + final int? parentId; + Mechanism({ required this.type, this.description, @@ -52,6 +84,10 @@ class Mechanism { this.synthetic, Map? meta, Map? data, + this.isExceptionGroup, + this.source, + this.exceptionId, + this.parentId, }) : _meta = meta != null ? Map.from(meta) : null, _data = data != null ? Map.from(data) : null; @@ -63,6 +99,10 @@ class Mechanism { Map? meta, Map? data, bool? synthetic, + bool? isExceptionGroup, + String? source, + int? exceptionId, + int? parentId, }) => Mechanism( type: type ?? this.type, @@ -72,6 +112,10 @@ class Mechanism { meta: meta ?? this.meta, data: data ?? this.data, synthetic: synthetic ?? this.synthetic, + isExceptionGroup: isExceptionGroup ?? this.isExceptionGroup, + source: source ?? this.source, + exceptionId: exceptionId ?? this.exceptionId, + parentId: parentId ?? this.parentId, ); /// Deserializes a [Mechanism] from JSON [Map]. @@ -94,6 +138,10 @@ class Mechanism { meta: meta, data: data, synthetic: json['synthetic'], + isExceptionGroup: json['is_exception_group'], + source: json['source'], + exceptionId: json['exception_id'], + parentId: json['parent_id'], ); } @@ -107,6 +155,10 @@ class Mechanism { if (_meta?.isNotEmpty ?? false) 'meta': _meta, if (_data?.isNotEmpty ?? false) 'data': _data, if (synthetic != null) 'synthetic': synthetic, + if (isExceptionGroup != null) 'is_exception_group': isExceptionGroup, + if (source != null) 'source': source, + if (exceptionId != null) 'exception_id': exceptionId, + if (parentId != null) 'parent_id': parentId, }; } } diff --git a/dart/test/protocol/mechanism_test.dart b/dart/test/protocol/mechanism_test.dart index 4b484d2ca3..7861f39e43 100644 --- a/dart/test/protocol/mechanism_test.dart +++ b/dart/test/protocol/mechanism_test.dart @@ -11,6 +11,10 @@ void main() { synthetic: true, meta: {'key': 'value'}, data: {'keyb': 'valueb'}, + isExceptionGroup: false, + exceptionId: 0, + parentId: 0, + source: 'source', ); final mechanismJson = { @@ -21,6 +25,10 @@ void main() { 'meta': {'key': 'value'}, 'data': {'keyb': 'valueb'}, 'synthetic': true, + 'isExceptionGroup': true, + 'exceptionId': 0, + 'parentId': 0, + 'source': 'source', }; group('json', () { @@ -51,6 +59,7 @@ void main() { expect(data.toJson(), copy.toJson()); }); + test('copyWith takes new values', () { final data = mechanism; @@ -62,6 +71,10 @@ void main() { synthetic: false, meta: {'key1': 'value1'}, data: {'keyb1': 'valueb1'}, + exceptionId: 1, + parentId: 1, + isExceptionGroup: false, + source: 'foo', ); expect('type1', copy.type); @@ -71,6 +84,10 @@ void main() { expect(false, copy.synthetic); expect({'key1': 'value1'}, copy.meta); expect({'keyb1': 'valueb1'}, copy.data); + expect(1, copy.exceptionId); + expect(1, copy.parentId); + expect(false, copy.isExceptionGroup); + expect('foo', copy.source); }); }); } From 8b62c192afb8b5b92e8587457c62be12317bf80e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Mon, 5 Feb 2024 19:30:59 +0100 Subject: [PATCH 2/6] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 262bdd0d7e..5f54221762 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ - Now the device context from Android is available in `BeforeSendCallback` - Set ip_address to {{auto}} by default, even if sendDefaultPII is disabled ([#1665](https://github.com/getsentry/sentry-dart/pull/1665)) - Instead use the "Prevent Storing of IP Addresses" option in the "Security & Privacy" project settings on sentry.io + +### Features + +- Add support for exception aggregates ([#xxxx](https://github.com/getsentry/sentry-dart/pull/xxxx)) ## 7.16.0 From c050ff7378f74d55510a665c57dfd930b0a02df3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Mon, 5 Feb 2024 19:34:47 +0100 Subject: [PATCH 3/6] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f54221762..3a3810f32c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ ### Features -- Add support for exception aggregates ([#xxxx](https://github.com/getsentry/sentry-dart/pull/xxxx)) +- Add support for exception aggregates ([#1866](https://github.com/getsentry/sentry-dart/pull/1866)) ## 7.16.0 From 9c32a6bb61e2ea399399ecd3c2f7f1c3f3cae642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Thu, 8 Feb 2024 11:26:48 +0100 Subject: [PATCH 4/6] fix json keys in test --- dart/test/protocol/mechanism_test.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dart/test/protocol/mechanism_test.dart b/dart/test/protocol/mechanism_test.dart index 7861f39e43..857a0529a9 100644 --- a/dart/test/protocol/mechanism_test.dart +++ b/dart/test/protocol/mechanism_test.dart @@ -25,10 +25,10 @@ void main() { 'meta': {'key': 'value'}, 'data': {'keyb': 'valueb'}, 'synthetic': true, - 'isExceptionGroup': true, - 'exceptionId': 0, - 'parentId': 0, + 'is_exception_group': false, 'source': 'source', + 'exception_id': 0, + 'parent_id': 0, }; group('json', () { From fafbc8abff67c80c430cb9bcbacaf9cac18b7a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Wed, 14 Feb 2024 19:17:21 +0100 Subject: [PATCH 5/6] Update dart/lib/src/protocol/mechanism.dart --- dart/lib/src/protocol/mechanism.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dart/lib/src/protocol/mechanism.dart b/dart/lib/src/protocol/mechanism.dart index 90bfe2cfeb..22a6356800 100644 --- a/dart/lib/src/protocol/mechanism.dart +++ b/dart/lib/src/protocol/mechanism.dart @@ -47,7 +47,7 @@ class Mechanism { /// An optional boolean value, set `true` when the exception is the exception /// group type specific to the platform or language. /// The default is false when omitted. - /// For example, exceptions of type (PlatformException)[https://api.flutter.dev/flutter/services/PlatformException-class.html] + /// For example, exceptions of type [PlatformException](https://api.flutter.dev/flutter/services/PlatformException-class.html) /// have set it to `true`, others are set to `false`. final bool? isExceptionGroup; From 4d2b36396a88f5edc5202f291f861233831c90a6 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 6 Mar 2024 10:24:54 +0100 Subject: [PATCH 6/6] Update CHANGELOG.md --- CHANGELOG.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4019e2f436..32e5a41b47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Features + +- Add support for exception aggregates ([#1866](https://github.com/getsentry/sentry-dart/pull/1866)) + ## 8.0.0-beta.2 ### Breaking Changes @@ -17,10 +23,6 @@ - Now the device context from Android is available in `BeforeSendCallback` - Set ip_address to {{auto}} by default, even if sendDefaultPII is disabled ([#1665](https://github.com/getsentry/sentry-dart/pull/1665)) - Instead use the "Prevent Storing of IP Addresses" option in the "Security & Privacy" project settings on sentry.io - -### Features - -- Add support for exception aggregates ([#1866](https://github.com/getsentry/sentry-dart/pull/1866)) ### Fixes