Skip to content

Commit 3fa0b79

Browse files
authored
feat: before breadcrumb and scope ref (#122)
1 parent b51b0da commit 3fa0b79

File tree

3 files changed

+78
-31
lines changed

3 files changed

+78
-31
lines changed

CHANGELOG.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,19 @@
1414
- remove the `package:args` dependency #94
1515
- move the `package:pedantic` to dev depencies #94
1616
- Added GH Action Changelog verifier #95
17-
- Added GH Action (CI) for Dart
17+
- Added GH Action (CI) for Dart #97
1818
- new Dart code file structure #96
1919
- Base the sdk name on the platform (`sentry.dart` for io & flutter, `sentry.dart.browser` in a browser context) #103
2020
- Single changelog and readme for both packages #105
2121
- new static API : Sentry.init(), Sentry.captureEvent() #108
2222
- expect a sdkName based on the test platform #105
2323
- Added Scope and Breadcrumb ring buffer #109
2424
- Added Hub to SDK #113
25-
- Ref: Hub passes the Scope to SentryClient
25+
- Ref: Hub passes the Scope to SentryClient #114
2626
- Feature: sentry options #116
27-
- Ref: SentryId generates UUID
28-
- Ref: Event now is SentryEvent and added GPU
27+
- Ref: SentryId generates UUID #119
28+
- Ref: Event now is SentryEvent and added GPU #121
29+
- Feat: before breadcrumb and scope ref. #122
2930

3031
# `package:sentry` changelog
3132

dart/lib/src/scope.dart

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,14 @@ import 'sentry_options.dart';
66
/// Scope data to be sent with the event
77
class Scope {
88
/// How important this event is.
9-
SentryLevel _level;
10-
11-
SentryLevel get level => _level;
12-
13-
set level(SentryLevel level) {
14-
_level = level;
15-
}
9+
SentryLevel level;
1610

1711
/// The name of the transaction which generated this event,
1812
/// for example, the route name: `"/users/<username>/"`.
19-
String _transaction;
20-
21-
String get transaction => _transaction;
22-
23-
set transaction(String transaction) {
24-
_transaction = transaction;
25-
}
13+
String transaction;
2614

2715
/// Information about the current user.
28-
User _user;
29-
30-
User get user => _user;
31-
32-
set user(User user) {
33-
_user = user;
34-
}
16+
User user;
3517

3618
/// Used to deduplicate events by grouping ones with the same fingerprint
3719
/// together.
@@ -71,21 +53,38 @@ class Scope {
7153

7254
Map<String, dynamic> get extra => Map.unmodifiable(_extra);
7355

74-
// TODO: EventProcessors, Contexts, BeforeBreadcrumbCallback, Breadcrumb Hint, clone
56+
// TODO: Contexts
57+
58+
/// Scope's event processor list
59+
final List<EventProcessor> _eventProcessors = [];
60+
61+
List<EventProcessor> get eventProcessors =>
62+
List.unmodifiable(_eventProcessors);
7563

7664
final SentryOptions _options;
7765

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

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

8472
// bail out if maxBreadcrumbs is zero
8573
if (_options.maxBreadcrumbs == 0) {
8674
return;
8775
}
8876

77+
// run before breadcrumb callback if set
78+
if (_options.beforeBreadcrumbCallback != null) {
79+
breadcrumb = _options.beforeBreadcrumbCallback(breadcrumb, hint);
80+
81+
if (breadcrumb == null) {
82+
_options.logger(
83+
SentryLevel.info, 'Breadcrumb was dropped by beforeBreadcrumb');
84+
return;
85+
}
86+
}
87+
8988
// remove first item if list if full
9089
if (_breadcrumbs.length >= _options.maxBreadcrumbs &&
9190
_breadcrumbs.isNotEmpty) {
@@ -100,15 +99,23 @@ class Scope {
10099
_breadcrumbs.clear();
101100
}
102101

102+
/// Adds an event processor
103+
void addEventProcessor(EventProcessor eventProcessor) {
104+
assert(eventProcessor != null, "EventProcessor can't be null");
105+
106+
_eventProcessors.add(eventProcessor);
107+
}
108+
103109
/// Resets the Scope to its default state
104110
void clear() {
105111
clearBreadcrumbs();
106-
_level = null;
107-
_transaction = null;
108-
_user = null;
112+
level = null;
113+
transaction = null;
114+
user = null;
109115
_fingerprint = null;
110116
_tags.clear();
111117
_extra.clear();
118+
_eventProcessors.clear();
112119
}
113120

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

145+
/// Clones the current Scope
138146
Scope clone() {
139147
final clone = Scope(_options)
140148
..user = user
@@ -153,6 +161,10 @@ class Scope {
153161
clone.addBreadcrumb(breadcrumb);
154162
}
155163

164+
for (final eventProcessor in _eventProcessors) {
165+
clone.addEventProcessor(eventProcessor);
166+
}
167+
156168
return clone;
157169
}
158170
}

dart/test/scope_test.dart

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,25 @@ void main() {
4848
expect(sut.breadcrumbs.last, breadcrumb);
4949
});
5050

51+
test('Executes and drops $Breadcrumb', () {
52+
final sut = fixture.getSut(
53+
beforeBreadcrumbCallback: fixture.beforeBreadcrumbCallback,
54+
);
55+
56+
final breadcrumb = Breadcrumb('test log', DateTime.utc(2019));
57+
sut.addBreadcrumb(breadcrumb);
58+
59+
expect(sut.breadcrumbs.length, 0);
60+
});
61+
62+
test('adds $EventProcessor', () {
63+
final sut = fixture.getSut();
64+
65+
sut.addEventProcessor(fixture.processor);
66+
67+
expect(sut.eventProcessors.last, fixture.processor);
68+
});
69+
5170
test('respects max $Breadcrumb', () {
5271
final maxBreadcrumbs = 2;
5372
final sut = fixture.getSut(maxBreadcrumbs: maxBreadcrumbs);
@@ -149,6 +168,8 @@ void main() {
149168
sut.setTag('test', 'test');
150169
sut.setExtra('test', 'test');
151170

171+
sut.addEventProcessor(fixture.processor);
172+
152173
sut.clear();
153174

154175
expect(sut.breadcrumbs.length, 0);
@@ -164,6 +185,8 @@ void main() {
164185
expect(sut.tags.length, 0);
165186

166187
expect(sut.extra.length, 0);
188+
189+
expect(sut.eventProcessors.length, 0);
167190
});
168191

169192
test('clones', () {
@@ -175,13 +198,24 @@ void main() {
175198
expect(sut.tags, clone.tags);
176199
expect(sut.breadcrumbs, clone.breadcrumbs);
177200
expect(ListEquality().equals(sut.fingerprint, clone.fingerprint), true);
201+
expect(ListEquality().equals(sut.eventProcessors, clone.eventProcessors),
202+
true);
178203
});
179204
}
180205

181206
class Fixture {
182-
Scope getSut({int maxBreadcrumbs = 100}) {
207+
Scope getSut({
208+
int maxBreadcrumbs = 100,
209+
BeforeBreadcrumbCallback beforeBreadcrumbCallback,
210+
}) {
183211
final options = SentryOptions();
184212
options.maxBreadcrumbs = maxBreadcrumbs;
213+
options.beforeBreadcrumbCallback = beforeBreadcrumbCallback;
185214
return Scope(options);
186215
}
216+
217+
SentryEvent processor(SentryEvent event, dynamic hint) => null;
218+
219+
Breadcrumb beforeBreadcrumbCallback(Breadcrumb breadcrumb, dynamic hint) =>
220+
null;
187221
}

0 commit comments

Comments
 (0)