diff --git a/dart/lib/src/sentry_client.dart b/dart/lib/src/sentry_client.dart index c319677832..95911b900b 100644 --- a/dart/lib/src/sentry_client.dart +++ b/dart/lib/src/sentry_client.dart @@ -84,6 +84,16 @@ class SentryClient { dynamic stackTrace, Hint? hint, }) async { + if (_options.isIgnoredError(event)) { + _options.logger( + SentryLevel.debug, + 'Error was ignored as specified in the ignoredErrors options.', + ); + _options.recorder + .recordLostEvent(DiscardReason.beforeSend, _getCategory(event)); + return _emptySentryId; + } + if (_options.containsIgnoredExceptionForType(event.throwable)) { _options.logger( SentryLevel.debug, @@ -351,6 +361,14 @@ class SentryClient { return _emptySentryId; } + if (_options.isIgnoredTransaction(preparedTransaction)) { + _options.logger( + SentryLevel.debug, + 'Transaction was ignored as specified in the ignoredTransactions options.', + ); + return _emptySentryId; + } + preparedTransaction = await _runBeforeSend(preparedTransaction, hint) as SentryTransaction?; diff --git a/dart/lib/src/sentry_options.dart b/dart/lib/src/sentry_options.dart index 636534fb5d..765ba382d9 100644 --- a/dart/lib/src/sentry_options.dart +++ b/dart/lib/src/sentry_options.dart @@ -184,6 +184,43 @@ class SentryOptions { /// sent. Events are picked randomly. Default is null (disabled) double? sampleRate; + /// The ignoreErrors tells the SDK which errors should be not sent to the sentry server. + /// If an null or an empty list is used, the SDK will send all transactions. + Iterable? ignoreErrors; + + bool isIgnoredError(SentryEvent event) { + if (ignoreErrors == null || + ignoreErrors!.isEmpty || + event.message == null) { + return false; + } + String combinedRegexPattern = ignoreErrors!.join('|'); + + RegExp regExp = RegExp(combinedRegexPattern); + + bool ignore = regExp.firstMatch(event.message!.formatted) != null; + + return ignore; + } + + /// The ignoreTransactions tells the SDK which transactions should be not sent to the sentry server. + /// If null or an empty list is used, the SDK will send all transactions. + Iterable? ignoreTransactions; + + bool isIgnoredTransaction(SentryTransaction transaction) { + if (ignoreTransactions == null || ignoreTransactions!.isEmpty) { + return false; + } + + String combinedRegexPattern = ignoreTransactions!.join('|'); + + RegExp regExp = RegExp(combinedRegexPattern); + + bool ignore = regExp.firstMatch(transaction.tracer.name) != null; + + return ignore; + } + final List _inAppExcludes = []; /// A list of string prefixes of packages names that do not belong to the app, but rather third-party diff --git a/dart/test/sentry_client_test.dart b/dart/test/sentry_client_test.dart index 5a2945a6ec..3889cc4f2b 100644 --- a/dart/test/sentry_client_test.dart +++ b/dart/test/sentry_client_test.dart @@ -1033,6 +1033,42 @@ void main() { }); }); + group('SentryClient ignored errors', () { + late Fixture fixture; + + setUp(() { + fixture = Fixture(); + fixture.options.ignoreErrors = ["my-error", "error-.*"]; + }); + + test('ignore Error "my-error"', () async { + final event = SentryEvent(message: SentryMessage("my-error")); + + final client = fixture.getSut(); + await client.captureEvent(event); + + expect((fixture.transport).called(0), true); + }); + + test('ignore Error "error-foo"', () async { + final event = SentryEvent(message: SentryMessage("error-foo")); + + final client = fixture.getSut(); + await client.captureEvent(event); + + expect((fixture.transport).called(0), true); + }); + + test('allow Error "warning"', () async { + final event = SentryEvent(message: SentryMessage("warning")); + + final client = fixture.getSut(); + await client.captureEvent(event); + + expect((fixture.transport).called(1), true); + }); + }); + group('SentryClient ignored exceptions', () { late Fixture fixture;