Skip to content

Commit d4120ac

Browse files
authored
Add option to opt out of fatal level for automatically collected errors (#1738)
1 parent 041d84d commit d4120ac

9 files changed

+82
-13
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Features
6+
7+
- Add option to opt out of fatal level for automatically collected errors ([#1738](https://github.com/getsentry/sentry-dart/pull/1738))
8+
39
## 7.13.2
410

511
### Fixes

dart/lib/src/run_zoned_guarded_integration.dart

+3-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ class RunZonedGuardedIntegration extends Integration<SentryOptions> {
5050

5151
final event = SentryEvent(
5252
throwable: throwableMechanism,
53-
level: SentryLevel.fatal,
53+
level: options.markAutomaticallyCollectedErrorsAsFatal
54+
? SentryLevel.fatal
55+
: SentryLevel.error,
5456
timestamp: hub.options.clock(),
5557
);
5658

dart/lib/src/sentry_isolate.dart

+3-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ class SentryIsolate {
7474
final throwableMechanism = ThrowableMechanism(mechanism, throwable);
7575
final event = SentryEvent(
7676
throwable: throwableMechanism,
77-
level: SentryLevel.fatal,
77+
level: hub.options.markAutomaticallyCollectedErrorsAsFatal
78+
? SentryLevel.fatal
79+
: SentryLevel.error,
7880
timestamp: hub.options.clock(),
7981
);
8082

dart/lib/src/sentry_options.dart

+5
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,11 @@ class SentryOptions {
369369
@internal
370370
bool automatedTestMode = false;
371371

372+
/// Errors that the SDK automatically collects, for example in
373+
/// [SentryIsolate], have `level` [SentryLevel.fatal] set per default.
374+
/// Settings this to `false` will set the `level` to [SentryLevel.error].
375+
bool markAutomaticallyCollectedErrorsAsFatal = true;
376+
372377
SentryOptions({this.dsn, PlatformChecker? checker}) {
373378
if (checker != null) {
374379
platformChecker = checker;

dart/test/run_zoned_guarded_integration_test.dart

+17
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,23 @@ void main() {
5454

5555
expect(onErrorCalled, true);
5656
});
57+
58+
test('sets level to error instead of fatal', () async {
59+
final exception = StateError('error');
60+
final stackTrace = StackTrace.current;
61+
62+
final hub = Hub(fixture.options);
63+
final client = MockSentryClient();
64+
hub.bindClient(client);
65+
66+
final sut = fixture.getSut(runner: () async {});
67+
68+
fixture.options.markAutomaticallyCollectedErrorsAsFatal = false;
69+
await sut.captureError(hub, fixture.options, exception, stackTrace);
70+
71+
final capturedEvent = client.captureEventCalls.last.event;
72+
expect(capturedEvent.level, SentryLevel.error);
73+
});
5774
});
5875
}
5976

dart/test/sentry_isolate_test.dart

+18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
@TestOn('vm')
22

33
import 'package:sentry/src/hub.dart';
4+
import 'package:sentry/src/protocol/sentry_level.dart';
45
import 'package:sentry/src/protocol/span_status.dart';
56
import 'package:sentry/src/sentry_isolate.dart';
67
import 'package:sentry/src/sentry_options.dart';
@@ -48,6 +49,23 @@ void main() {
4849

4950
await span?.finish();
5051
});
52+
53+
test('sets level to error instead of fatal', () async {
54+
final exception = StateError('error');
55+
final stackTrace = StackTrace.current.toString();
56+
57+
final hub = Hub(fixture.options);
58+
final client = MockSentryClient();
59+
hub.bindClient(client);
60+
61+
fixture.options.markAutomaticallyCollectedErrorsAsFatal = false;
62+
63+
await SentryIsolate.handleIsolateError(
64+
hub, [exception.toString(), stackTrace]);
65+
66+
final capturedEvent = client.captureEventCalls.last.event;
67+
expect(capturedEvent.level, SentryLevel.error);
68+
});
5169
});
5270
}
5371

flutter/lib/src/integrations/flutter_error_integration.dart

+3-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ class FlutterErrorIntegration implements Integration<SentryFlutterOptions> {
6363

6464
var event = SentryEvent(
6565
throwable: throwableMechanism,
66-
level: SentryLevel.fatal,
66+
level: options.markAutomaticallyCollectedErrorsAsFatal
67+
? SentryLevel.fatal
68+
: SentryLevel.error,
6769
contexts: flutterErrorDetails.isNotEmpty
6870
? (Contexts()..['flutter_error_details'] = flutterErrorDetails)
6971
: null,

flutter/lib/src/native/cocoa/binding.dart

+13-10
Original file line numberDiff line numberDiff line change
@@ -37603,7 +37603,8 @@ class ObjCBlock_bool_ObjCObject_ffiUnsignedLong_bool extends _ObjCBlockBase {
3760337603
ObjCBlock_bool_ObjCObject_ffiUnsignedLong_bool.fromFunctionPointer(
3760437604
SentryCocoa lib,
3760537605
ffi.Pointer<
37606-
ffi.NativeFunction<
37606+
ffi
37607+
.NativeFunction<
3760737608
ffi.Bool Function(ffi.Pointer<ObjCObject> arg0,
3760837609
ffi.UnsignedLong arg1, ffi.Pointer<ffi.Bool> arg2)>>
3760937610
ptr)
@@ -42031,15 +42032,17 @@ class ObjCBlock_bool_ObjCObject_bool extends _ObjCBlockBase {
4203142032
ffi.Pointer<ffi.Bool> arg1)>>
4203242033
ptr)
4203342034
: this._(
42034-
lib._newBlock1(
42035-
_cFuncTrampoline ??= ffi.Pointer.fromFunction<
42036-
ffi.Bool Function(
42037-
ffi.Pointer<_ObjCBlock> block,
42038-
ffi.Pointer<ObjCObject> arg0,
42039-
ffi.Pointer<ffi.Bool> arg1)>(
42040-
_ObjCBlock_bool_ObjCObject_bool_fnPtrTrampoline, false)
42041-
.cast(),
42042-
ptr.cast()),
42035+
lib
42036+
._newBlock1(
42037+
_cFuncTrampoline ??= ffi.Pointer.fromFunction<
42038+
ffi.Bool Function(
42039+
ffi.Pointer<_ObjCBlock> block,
42040+
ffi.Pointer<ObjCObject> arg0,
42041+
ffi.Pointer<ffi.Bool> arg1)>(
42042+
_ObjCBlock_bool_ObjCObject_bool_fnPtrTrampoline,
42043+
false)
42044+
.cast(),
42045+
ptr.cast()),
4204342046
lib);
4204442047
static ffi.Pointer<ffi.Void>? _cFuncTrampoline;
4204542048

flutter/test/integrations/flutter_error_integration_test.dart

+14
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,20 @@ void main() {
246246

247247
await span?.finish();
248248
});
249+
250+
test('captures error with level error', () async {
251+
final exception = StateError('error');
252+
253+
fixture.options.markAutomaticallyCollectedErrorsAsFatal = false;
254+
255+
_reportError(exception: exception);
256+
257+
final event = verify(
258+
await fixture.hub.captureEvent(captureAny, hint: anyNamed('hint')),
259+
).captured.first as SentryEvent;
260+
261+
expect(event.level, SentryLevel.error);
262+
});
249263
});
250264
}
251265

0 commit comments

Comments
 (0)