Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: execute before breadcrumb on scope
  • Loading branch information
marandaneto committed Oct 21, 2020
commit 53d5d0df81931179e9c74862a71c11f2abdf28d0
62 changes: 37 additions & 25 deletions dart/lib/src/scope.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,14 @@ import 'sentry_options.dart';
/// Scope data to be sent with the event
class Scope {
/// How important this event is.
SentryLevel _level;

SentryLevel get level => _level;

set level(SentryLevel level) {
_level = level;
}
SentryLevel level;

/// The name of the transaction which generated this event,
/// for example, the route name: `"/users/<username>/"`.
String _transaction;

String get transaction => _transaction;

set transaction(String transaction) {
_transaction = transaction;
}
String transaction;

/// Information about the current user.
User _user;

User get user => _user;

set user(User user) {
_user = user;
}
User user;

/// Used to deduplicate events by grouping ones with the same fingerprint
/// together.
Expand Down Expand Up @@ -73,19 +55,36 @@ class Scope {

// TODO: EventProcessors, Contexts, BeforeBreadcrumbCallback, Breadcrumb Hint, clone

/// Scope's event processor list
final List<EventProcessor> _eventProcessors = [];

List<EventProcessor> get eventProcessors =>
List.unmodifiable(_eventProcessors);

final SentryOptions _options;

Scope(this._options) : assert(_options != null, 'SentryOptions is required');

/// Adds a breadcrumb to the breadcrumbs queue
void addBreadcrumb(Breadcrumb breadcrumb) {
void addBreadcrumb(Breadcrumb breadcrumb, {dynamic hint}) {
assert(breadcrumb != null, "Breadcrumb can't be null");

// bail out if maxBreadcrumbs is zero
if (_options.maxBreadcrumbs == 0) {
return;
}

// run before breadcrumb callback if set
if (_options.beforeBreadcrumbCallback != null) {
breadcrumb = _options.beforeBreadcrumbCallback(breadcrumb, hint);

if (breadcrumb == null) {
_options.logger(
SentryLevel.info, 'Breadcrumb was dropped by beforeBreadcrumb');
return;
}
}

// remove first item if list if full
if (_breadcrumbs.length >= _options.maxBreadcrumbs &&
_breadcrumbs.isNotEmpty) {
Expand All @@ -100,15 +99,23 @@ class Scope {
_breadcrumbs.clear();
}

/// Adds an event processor
void addEventProcessor(EventProcessor eventProcessor) {
assert(eventProcessor != null, "EventProcessor can't be null");

_eventProcessors.add(eventProcessor);
}

/// Resets the Scope to its default state
void clear() {
clearBreadcrumbs();
_level = null;
_transaction = null;
_user = null;
level = null;
transaction = null;
user = null;
_fingerprint = null;
_tags.clear();
_extra.clear();
_eventProcessors.clear();
}

/// Sets a tag to the Scope
Expand All @@ -135,6 +142,7 @@ class Scope {
/// Removes an extra from the Scope
void removeExtra(String key) => _extra.remove(key);

/// Clones the current Scope
Scope clone() {
final clone = Scope(_options)
..user = user
Expand All @@ -153,6 +161,10 @@ class Scope {
clone.addBreadcrumb(breadcrumb);
}

for (final eventProcessor in _eventProcessors) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we're in the class, what about a private constructor or factory method that takes all fields as named args?
Then we could just clone all lists etc like Scope({eventProcessors = [...this.eventprocessors]) and avoid tall these for

Copy link
Contributor Author

@marandaneto marandaneto Oct 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mm yeah but rethinking this right now, maybe it'd make sense to just do a copyWith and follow the convention? tbh I just added the missing field in the existent method, I will check whats the state of the art for cloning objects on Dart.
Factory is public afaik, but a private ctor would work as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://pub.dev/documentation/copyable/latest/#examples
using the copyable interface seems to be the standard

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add this as a task on our project, so I can merge this now

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copyWith is probably the "most standard way" ( used a lot in Flutter source code, and in https://pub.dev/packages/freezed, a popular immutable package)

clone.addEventProcessor(eventProcessor);
}

return clone;
}
}
32 changes: 31 additions & 1 deletion dart/test/scope_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,25 @@ void main() {
expect(sut.breadcrumbs.last, breadcrumb);
});

test('Executes and drops $Breadcrumb', () {
final sut = fixture.getSut(
beforeBreadcrumbCallback: fixture.beforeBreadcrumbCallback,
);

final breadcrumb = Breadcrumb('test log', DateTime.utc(2019));
sut.addBreadcrumb(breadcrumb);

expect(sut.breadcrumbs.length, 0);
});

test('adds $EventProcessor', () {
final sut = fixture.getSut();

sut.addEventProcessor(fixture.processor);

expect(sut.eventProcessors.last, fixture.processor);
});

test('respects max $Breadcrumb', () {
final maxBreadcrumbs = 2;
final sut = fixture.getSut(maxBreadcrumbs: maxBreadcrumbs);
Expand Down Expand Up @@ -175,13 +194,24 @@ void main() {
expect(sut.tags, clone.tags);
expect(sut.breadcrumbs, clone.breadcrumbs);
expect(ListEquality().equals(sut.fingerprint, clone.fingerprint), true);
expect(ListEquality().equals(sut.eventProcessors, clone.eventProcessors),
true);
});
}

class Fixture {
Scope getSut({int maxBreadcrumbs = 100}) {
Scope getSut({
int maxBreadcrumbs = 100,
BeforeBreadcrumbCallback beforeBreadcrumbCallback,
}) {
final options = SentryOptions();
options.maxBreadcrumbs = maxBreadcrumbs;
options.beforeBreadcrumbCallback = beforeBreadcrumbCallback;
return Scope(options);
}

Event processor(Event event, dynamic hint) => null;

Breadcrumb beforeBreadcrumbCallback(Breadcrumb breadcrumb, dynamic hint) =>
null;
}