Skip to content

Commit 102f0e5

Browse files
committed
modified code to go through stacktrace frames
1 parent a4c0d59 commit 102f0e5

File tree

3 files changed

+121
-59
lines changed

3 files changed

+121
-59
lines changed

flutter/lib/src/event_processor/url_filter/html_url_filter_event_processor.dart

+21-5
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,40 @@ class WebUrlFilterEventProcessor implements UrlFilterEventProcessor {
1515
this._options,
1616
);
1717

18-
final html.Window _window = html.window;
19-
2018
final SentryFlutterOptions _options;
2119

2220
@override
2321
SentryEvent? apply(SentryEvent event, Hint hint) {
24-
final url = event.request?.url ?? _window.location.toString();
22+
final frames = _getStacktraceFrames(event);
23+
final lastPath = frames?.first?.absPath;
24+
25+
if (lastPath == null) {
26+
return event;
27+
}
2528

2629
if (_options.allowUrls.isNotEmpty &&
27-
!isMatchingRegexPattern(url, _options.allowUrls)) {
30+
!isMatchingRegexPattern(lastPath, _options.allowUrls)) {
2831
return null;
2932
}
3033

3134
if (_options.denyUrls.isNotEmpty &&
32-
isMatchingRegexPattern(url, _options.denyUrls)) {
35+
isMatchingRegexPattern(lastPath, _options.denyUrls)) {
3336
return null;
3437
}
3538

3639
return event;
3740
}
41+
42+
Iterable<SentryStackFrame?>? _getStacktraceFrames(SentryEvent event) {
43+
if (event.exceptions?.isNotEmpty == true) {
44+
return event.exceptions?.first.stackTrace?.frames;
45+
}
46+
if (event.threads?.isNotEmpty == true) {
47+
final stacktraces = event.threads?.map((e) => e.stacktrace);
48+
return stacktraces
49+
?.where((element) => element != null)
50+
.expand((element) => element!.frames);
51+
}
52+
return null;
53+
}
3854
}

flutter/lib/src/event_processor/url_filter/web_url_filter_event_processor.dart

+21-5
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,40 @@ class WebUrlFilterEventProcessor implements UrlFilterEventProcessor {
1717
this._options,
1818
);
1919

20-
final web.Window _window = web.window;
21-
2220
final SentryFlutterOptions _options;
2321

2422
@override
2523
SentryEvent? apply(SentryEvent event, Hint hint) {
26-
final url = event.request?.url ?? _window.location.toString();
24+
final frames = _getStacktraceFrames(event);
25+
final lastPath = frames?.first?.absPath;
26+
27+
if (lastPath == null) {
28+
return event;
29+
}
2730

2831
if (_options.allowUrls.isNotEmpty &&
29-
!isMatchingRegexPattern(url, _options.allowUrls)) {
32+
!isMatchingRegexPattern(lastPath, _options.allowUrls)) {
3033
return null;
3134
}
3235

3336
if (_options.denyUrls.isNotEmpty &&
34-
isMatchingRegexPattern(url, _options.denyUrls)) {
37+
isMatchingRegexPattern(lastPath, _options.denyUrls)) {
3538
return null;
3639
}
3740

3841
return event;
3942
}
43+
44+
Iterable<SentryStackFrame?>? _getStacktraceFrames(SentryEvent event) {
45+
if (event.exceptions?.isNotEmpty == true) {
46+
return event.exceptions?.first.stackTrace?.frames;
47+
}
48+
if (event.threads?.isNotEmpty == true) {
49+
final stacktraces = event.threads?.map((e) => e.stacktrace);
50+
return stacktraces
51+
?.where((element) => element != null)
52+
.expand((element) => element!.frames);
53+
}
54+
return null;
55+
}
4056
}

flutter/test/event_processor/url_filter/web_url_filter_event_processor_test.dart

+79-49
Original file line numberDiff line numberDiff line change
@@ -30,113 +30,133 @@ void main() {
3030

3131
test('returns null if allowUrl is set and does not match with url',
3232
() async {
33-
SentryEvent? event = SentryEvent(
34-
request: SentryRequest(
35-
url: 'foo.bar',
36-
),
37-
);
33+
final event = _createEventWithException("foo.bar");
3834
fixture.options.allowUrls = ["another.url"];
3935

4036
var eventProcessor = fixture.getSut();
41-
event = await eventProcessor.apply(event, Hint());
37+
final processedEvent = await eventProcessor.apply(event, Hint());
4238

43-
expect(event, isNull);
39+
expect(processedEvent, isNull);
4440
});
4541

4642
test('returns event if allowUrl is set and does partially match with url',
4743
() async {
48-
SentryEvent? event = SentryEvent(
49-
request: SentryRequest(
50-
url: 'foo.bar',
51-
),
52-
);
44+
final event = _createEventWithException("foo.bar");
5345
fixture.options.allowUrls = ["bar"];
5446

5547
var eventProcessor = fixture.getSut();
56-
event = await eventProcessor.apply(event, Hint());
48+
final processedEvent = await eventProcessor.apply(event, Hint());
5749

58-
expect(event, isNotNull);
50+
expect(processedEvent, isNotNull);
5951
});
6052

6153
test('returns event if denyUrl is set and does not match with url',
6254
() async {
63-
SentryEvent? event = SentryEvent(
64-
request: SentryRequest(
65-
url: 'foo.bar',
66-
),
67-
);
55+
final event = _createEventWithException("foo.bar");
6856
fixture.options.denyUrls = ["another.url"];
6957

7058
var eventProcessor = fixture.getSut();
71-
event = await eventProcessor.apply(event, Hint());
59+
final processedEvent = await eventProcessor.apply(event, Hint());
7260

73-
expect(event, isNotNull);
61+
expect(processedEvent, isNotNull);
7462
});
7563

7664
test('returns null if denyUrl is set and partially matches with url',
7765
() async {
78-
SentryEvent? event = SentryEvent(
79-
request: SentryRequest(
80-
url: 'foo.bar',
81-
),
82-
);
66+
final event = _createEventWithException("foo.bar");
8367
fixture.options.denyUrls = ["bar"];
8468

8569
var eventProcessor = fixture.getSut();
86-
event = await eventProcessor.apply(event, Hint());
70+
final processedEvent = await eventProcessor.apply(event, Hint());
8771

88-
expect(event, isNull);
72+
expect(processedEvent, isNull);
8973
});
9074

9175
test(
9276
'returns null if it is part of the allowed domain, but blocked for subdomain',
9377
() async {
94-
SentryEvent? event = SentryEvent(
95-
request: SentryRequest(
96-
url: 'this.is/a/special/url/for-testing/this-feature',
97-
),
98-
);
78+
final event = _createEventWithException(
79+
"this.is/a/special/url/for-testing/this-feature");
80+
9981
fixture.options.allowUrls = ["^this.is/.*\$"];
10082
fixture.options.denyUrls = ["special"];
10183

10284
var eventProcessor = fixture.getSut();
103-
event = await eventProcessor.apply(event, Hint());
85+
final processedEvent = await eventProcessor.apply(event, Hint());
10486

105-
expect(event, isNull);
87+
expect(processedEvent, isNull);
10688
});
10789

10890
test(
10991
'returns event if it is part of the allowed domain, and not of the blocked for subdomain',
11092
() async {
111-
SentryEvent? event = SentryEvent(
112-
request: SentryRequest(
113-
url: 'this.is/a/test/url/for-testing/this-feature',
114-
),
115-
);
93+
final event = _createEventWithException(
94+
"this.is/a/test/url/for-testing/this-feature");
11695
fixture.options.allowUrls = ["^this.is/.*\$"];
11796
fixture.options.denyUrls = ["special"];
11897

11998
var eventProcessor = fixture.getSut();
120-
event = await eventProcessor.apply(event, Hint());
99+
final processedEvent = await eventProcessor.apply(event, Hint());
121100

122-
expect(event, isNotNull);
101+
expect(processedEvent, isNotNull);
123102
});
124103

125104
test(
126105
'returns null if it is not part of the allowed domain, and not of the blocked for subdomain',
127106
() async {
128-
SentryEvent? event = SentryEvent(
129-
request: SentryRequest(
130-
url: 'another.url/for/a/test/testing/this-feature',
131-
),
132-
);
107+
final event = _createEventWithException(
108+
"another.url/for/a/test/testing/this-feature");
133109
fixture.options.allowUrls = ["^this.is/.*\$"];
134110
fixture.options.denyUrls = ["special"];
135111

136112
var eventProcessor = fixture.getSut();
137-
event = await eventProcessor.apply(event, Hint());
113+
final processedEvent = await eventProcessor.apply(event, Hint());
114+
115+
expect(processedEvent, isNull);
116+
});
117+
118+
test(
119+
'returns event if denyUrl is set and not matching with url of first exception',
120+
() async {
121+
final frame1 = SentryStackFrame(absPath: "test.url");
122+
final st1 = SentryStackTrace(frames: [frame1]);
123+
final exception1 = SentryException(
124+
type: "test-type", value: "test-value", stackTrace: st1);
125+
126+
final frame2 = SentryStackFrame(absPath: "foo.bar");
127+
final st2 = SentryStackTrace(frames: [frame2]);
128+
final exception2 = SentryException(
129+
type: "test-type", value: "test-value", stackTrace: st2);
130+
131+
SentryEvent event = SentryEvent(exceptions: [exception1, exception2]);
132+
133+
fixture.options.denyUrls = ["bar"];
134+
135+
var eventProcessor = fixture.getSut();
136+
final processedEvent = await eventProcessor.apply(event, Hint());
138137

139-
expect(event, isNull);
138+
expect(processedEvent, isNotNull);
139+
});
140+
141+
test(
142+
'returns event if denyUrl is set and not matching with url of first stacktraceframe',
143+
() async {
144+
final frame1 = SentryStackFrame(absPath: "test.url");
145+
final st1 = SentryStackTrace(frames: [frame1]);
146+
final thread1 = SentryThread(stacktrace: st1);
147+
148+
final frame2 = SentryStackFrame(absPath: "foo.bar");
149+
final st2 = SentryStackTrace(frames: [frame2]);
150+
final thread2 = SentryThread(stacktrace: st2);
151+
152+
SentryEvent event = SentryEvent(threads: [thread1, thread2]);
153+
154+
fixture.options.denyUrls = ["bar"];
155+
156+
var eventProcessor = fixture.getSut();
157+
final processedEvent = await eventProcessor.apply(event, Hint());
158+
159+
expect(processedEvent, isNotNull);
140160
});
141161
});
142162
}
@@ -147,3 +167,13 @@ class Fixture {
147167
return UrlFilterEventProcessor(options);
148168
}
149169
}
170+
171+
SentryEvent _createEventWithException(String url) {
172+
final frame = SentryStackFrame(absPath: url);
173+
final st = SentryStackTrace(frames: [frame]);
174+
final exception =
175+
SentryException(type: "test-type", value: "test-value", stackTrace: st);
176+
SentryEvent event = SentryEvent(exceptions: [exception]);
177+
178+
return event;
179+
}

0 commit comments

Comments
 (0)