Skip to content

Commit

Permalink
Add option to opt out of fatal level for automatically collected erro…
Browse files Browse the repository at this point in the history
…rs (#1738)
  • Loading branch information
denrase authored and buenaflor committed Nov 29, 2023
1 parent 9beda56 commit edb20db
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 13 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Features

- Add option to opt out of fatal level for automatically collected errors ([#1738](https://github.com/getsentry/sentry-dart/pull/1738))

## 7.13.2

### Fixes
Expand Down
4 changes: 3 additions & 1 deletion dart/lib/src/run_zoned_guarded_integration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ class RunZonedGuardedIntegration extends Integration<SentryOptions> {

final event = SentryEvent(
throwable: throwableMechanism,
level: SentryLevel.fatal,
level: options.markAutomaticallyCollectedErrorsAsFatal
? SentryLevel.fatal
: SentryLevel.error,
timestamp: hub.options.clock(),
);

Expand Down
4 changes: 3 additions & 1 deletion dart/lib/src/sentry_isolate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ class SentryIsolate {
final throwableMechanism = ThrowableMechanism(mechanism, throwable);
final event = SentryEvent(
throwable: throwableMechanism,
level: SentryLevel.fatal,
level: hub.options.markAutomaticallyCollectedErrorsAsFatal
? SentryLevel.fatal
: SentryLevel.error,
timestamp: hub.options.clock(),
);

Expand Down
5 changes: 5 additions & 0 deletions dart/lib/src/sentry_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,11 @@ class SentryOptions {
@internal
bool automatedTestMode = false;

/// Errors that the SDK automatically collects, for example in
/// [SentryIsolate], have `level` [SentryLevel.fatal] set per default.
/// Settings this to `false` will set the `level` to [SentryLevel.error].
bool markAutomaticallyCollectedErrorsAsFatal = true;

SentryOptions({this.dsn, PlatformChecker? checker}) {
if (checker != null) {
platformChecker = checker;
Expand Down
17 changes: 17 additions & 0 deletions dart/test/run_zoned_guarded_integration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,23 @@ void main() {

expect(onErrorCalled, true);
});

test('sets level to error instead of fatal', () async {
final exception = StateError('error');
final stackTrace = StackTrace.current;

final hub = Hub(fixture.options);
final client = MockSentryClient();
hub.bindClient(client);

final sut = fixture.getSut(runner: () async {});

fixture.options.markAutomaticallyCollectedErrorsAsFatal = false;
await sut.captureError(hub, fixture.options, exception, stackTrace);

final capturedEvent = client.captureEventCalls.last.event;
expect(capturedEvent.level, SentryLevel.error);
});
});
}

Expand Down
18 changes: 18 additions & 0 deletions dart/test/sentry_isolate_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@TestOn('vm')

import 'package:sentry/src/hub.dart';
import 'package:sentry/src/protocol/sentry_level.dart';
import 'package:sentry/src/protocol/span_status.dart';
import 'package:sentry/src/sentry_isolate.dart';
import 'package:sentry/src/sentry_options.dart';
Expand Down Expand Up @@ -48,6 +49,23 @@ void main() {

await span?.finish();
});

test('sets level to error instead of fatal', () async {
final exception = StateError('error');
final stackTrace = StackTrace.current.toString();

final hub = Hub(fixture.options);
final client = MockSentryClient();
hub.bindClient(client);

fixture.options.markAutomaticallyCollectedErrorsAsFatal = false;

await SentryIsolate.handleIsolateError(
hub, [exception.toString(), stackTrace]);

final capturedEvent = client.captureEventCalls.last.event;
expect(capturedEvent.level, SentryLevel.error);
});
});
}

Expand Down
4 changes: 3 additions & 1 deletion flutter/lib/src/integrations/flutter_error_integration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ class FlutterErrorIntegration implements Integration<SentryFlutterOptions> {

var event = SentryEvent(
throwable: throwableMechanism,
level: SentryLevel.fatal,
level: options.markAutomaticallyCollectedErrorsAsFatal
? SentryLevel.fatal
: SentryLevel.error,
contexts: flutterErrorDetails.isNotEmpty
? (Contexts()..['flutter_error_details'] = flutterErrorDetails)
: null,
Expand Down
23 changes: 13 additions & 10 deletions flutter/lib/src/native/cocoa/binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37603,7 +37603,8 @@ class ObjCBlock_bool_ObjCObject_ffiUnsignedLong_bool extends _ObjCBlockBase {
ObjCBlock_bool_ObjCObject_ffiUnsignedLong_bool.fromFunctionPointer(
SentryCocoa lib,
ffi.Pointer<
ffi.NativeFunction<
ffi
.NativeFunction<
ffi.Bool Function(ffi.Pointer<ObjCObject> arg0,
ffi.UnsignedLong arg1, ffi.Pointer<ffi.Bool> arg2)>>
ptr)
Expand Down Expand Up @@ -42031,15 +42032,17 @@ class ObjCBlock_bool_ObjCObject_bool extends _ObjCBlockBase {
ffi.Pointer<ffi.Bool> arg1)>>
ptr)
: this._(
lib._newBlock1(
_cFuncTrampoline ??= ffi.Pointer.fromFunction<
ffi.Bool Function(
ffi.Pointer<_ObjCBlock> block,
ffi.Pointer<ObjCObject> arg0,
ffi.Pointer<ffi.Bool> arg1)>(
_ObjCBlock_bool_ObjCObject_bool_fnPtrTrampoline, false)
.cast(),
ptr.cast()),
lib
._newBlock1(
_cFuncTrampoline ??= ffi.Pointer.fromFunction<
ffi.Bool Function(
ffi.Pointer<_ObjCBlock> block,
ffi.Pointer<ObjCObject> arg0,
ffi.Pointer<ffi.Bool> arg1)>(
_ObjCBlock_bool_ObjCObject_bool_fnPtrTrampoline,
false)
.cast(),
ptr.cast()),
lib);
static ffi.Pointer<ffi.Void>? _cFuncTrampoline;

Expand Down
14 changes: 14 additions & 0 deletions flutter/test/integrations/flutter_error_integration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,20 @@ void main() {

await span?.finish();
});

test('captures error with level error', () async {
final exception = StateError('error');

fixture.options.markAutomaticallyCollectedErrorsAsFatal = false;

_reportError(exception: exception);

final event = verify(
await fixture.hub.captureEvent(captureAny, hint: anyNamed('hint')),
).captured.first as SentryEvent;

expect(event.level, SentryLevel.error);
});
});
}

Expand Down

0 comments on commit edb20db

Please sign in to comment.