diff --git a/CHANGELOG.md b/CHANGELOG.md index 55f26e7c95..ebf27f42d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ - Fix: Integrations are executed on Hub creation - Fix: NoOp encode for Web - Fix: Breadcrumb data should accept serializable types and not only String values +- Ref: added Scope.applyToEvent # `package:sentry` changelog diff --git a/dart/lib/src/client.dart b/dart/lib/src/client.dart index f861a07c4e..3728020004 100644 --- a/dart/lib/src/client.dart +++ b/dart/lib/src/client.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'dart:math'; -import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; import 'package:sentry/src/transport/noop_transport.dart'; @@ -44,20 +43,18 @@ abstract class SentryClient { return emptyFuture; } - event = _applyScope(event: event, scope: scope); + if (scope != null) { + event = scope.applyToEvent(event, hint); + } else { + _options.logger(SentryLevel.debug, 'No scope is defined'); + } // dropped by scope event processors if (event == null) { return emptyFuture; } - // TODO create eventProcessors ? - event = event.copyWith( - serverName: _options.serverName, - environment: _options.environment, - release: _options.release, - platform: event.platform ?? sdkPlatform, - ); + event = _prepareEvent(event); if (_options.beforeSendCallback != null) { try { @@ -77,6 +74,16 @@ abstract class SentryClient { return _options.transport.send(event); } + SentryEvent _prepareEvent(SentryEvent event) => event.copyWith( + serverName: event.serverName ?? _options.serverName, + dist: event.dist ?? _options.dist, + environment: + event.environment ?? _options.environment ?? defaultEnvironment, + release: event.release ?? _options.release, + sdk: event.sdk ?? _options.sdk, + platform: event.platform ?? sdkPlatform, + ); + /// Reports the [throwable] and optionally its [stackTrace] to Sentry.io. Future captureException( dynamic throwable, { @@ -142,51 +149,6 @@ abstract class SentryClient { return event; } - SentryEvent _applyScope({ - @required SentryEvent event, - @required Scope scope, - }) { - if (scope != null) { - // Merge the scope transaction. - if (event.transaction == null) { - event = event.copyWith(transaction: scope.transaction); - } - - // Merge the user context. - if (event.userContext == null) { - event = event.copyWith(userContext: scope.user); - } - - // Merge the scope fingerprint. - if (event.fingerprint == null) { - event = event.copyWith(fingerprint: scope.fingerprint); - } - - // Merge the scope breadcrumbs. - if (event.breadcrumbs == null) { - event = event.copyWith(breadcrumbs: scope.breadcrumbs); - } - - // Merge the scope tags. - event = event.copyWith( - tags: scope.tags.map((key, value) => MapEntry(key, value)) - ..addAll(event.tags ?? {})); - - // Merge the scope extra. - event = event.copyWith( - extra: scope.extra.map((key, value) => MapEntry(key, value)) - ..addAll(event.extra ?? {})); - - // Merge the scope level. - if (scope.level != null) { - event = event.copyWith(level: scope.level); - } - - // TODO: execute scope event processors - } - return event; - } - bool _sampleRate() { if (_options.sampleRate != null && _random != null) { return (_options.sampleRate < _random.nextDouble()); diff --git a/dart/lib/src/protocol/sentry_event.dart b/dart/lib/src/protocol/sentry_event.dart index e721a485fc..76025aaf35 100644 --- a/dart/lib/src/protocol/sentry_event.dart +++ b/dart/lib/src/protocol/sentry_event.dart @@ -12,7 +12,7 @@ class SentryEvent { SentryEvent({ SentryId eventId, DateTime timestamp, - Sdk sdk, + this.sdk, this.platform, this.logger, this.serverName, @@ -33,8 +33,7 @@ class SentryEvent { this.contexts, this.breadcrumbs, }) : eventId = eventId ?? SentryId.newId(), - timestamp = timestamp ?? getUtcDateTime(), - sdk = sdk ?? Sdk(name: sdkName, version: sdkVersion); + timestamp = timestamp ?? getUtcDateTime(); /// Refers to the default fingerprinting algorithm. /// diff --git a/dart/lib/src/scope.dart b/dart/lib/src/scope.dart index 4927fcaa5b..4854955eba 100644 --- a/dart/lib/src/scope.dart +++ b/dart/lib/src/scope.dart @@ -142,6 +142,46 @@ class Scope { /// Removes an extra from the Scope void removeExtra(String key) => _extra.remove(key); + SentryEvent applyToEvent(SentryEvent event, dynamic hint) { + event = event.copyWith( + transaction: event.transaction ?? transaction, + userContext: event.userContext ?? user, + fingerprint: event.fingerprint ?? fingerprint, + breadcrumbs: event.breadcrumbs ?? breadcrumbs, + tags: tags.isNotEmpty ? _mergeEventTags(event) : event.tags, + extra: extra.isNotEmpty ? _mergeEventExtra(event) : event.extra, + level: level ?? event.level, + ); + + for (final processor in _eventProcessors) { + try { + event = processor(event, hint); + } catch (err) { + _options.logger( + SentryLevel.error, + 'An exception occurred while processing event by a processor : $err', + ); + } + if (event == null) { + _options.logger(SentryLevel.debug, 'Event was dropped by a processor'); + break; + } + } + + return event; + } + + /// the event tags will be kept + /// if the scope and the event have tag entries with the same key, + Map _mergeEventTags(SentryEvent event) => + tags.map((key, value) => MapEntry(key, value))..addAll(event.tags ?? {}); + + /// if the scope and the event have extra entries with the same key, + /// the event extra will be kept + Map _mergeEventExtra(SentryEvent event) => + extra.map((key, value) => MapEntry(key, value)) + ..addAll(event.extra ?? {}); + /// Clones the current Scope Scope clone() { final clone = Scope(_options) diff --git a/dart/lib/src/sentry_options.dart b/dart/lib/src/sentry_options.dart index 1a38bfc126..fbef8248c6 100644 --- a/dart/lib/src/sentry_options.dart +++ b/dart/lib/src/sentry_options.dart @@ -7,6 +7,8 @@ import 'hub.dart'; import 'protocol.dart'; import 'utils.dart'; +const defaultEnvironment = 'production'; + /// Sentry SDK options class SentryOptions { /// Default Log level if not specified Default is DEBUG @@ -98,7 +100,6 @@ class SentryOptions { /// Sets the release. SDK will try to automatically configure a release out of the box String release; -// TODO: probably its part of environmentAttributes /// Sets the environment. This string is freeform and not set by default. A release can be /// associated with more than one environment to separate them in the UI Think staging vs prod or /// similar. @@ -137,8 +138,14 @@ class SentryOptions { /// The server name used in the Sentry messages. String serverName; + Sdk _sdk = Sdk(name: sdkName, version: sdkVersion); + /// Sdk object that contains the Sentry Client Name and its version - Sdk sdk; + Sdk get sdk => _sdk; + + set sdk(Sdk sdk) { + _sdk = sdk ?? _sdk; + } // TODO: Scope observers, enableScopeSync