Skip to content

Commit 02e6d11

Browse files
authored
fix(core): Fix allowUrls and denyUrls for linked and aggregate exceptions (#15521)
1 parent e8b3bb2 commit 02e6d11

File tree

3 files changed

+118
-9
lines changed

3 files changed

+118
-9
lines changed

.size-limit.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ module.exports = [
4747
path: 'packages/browser/build/npm/esm/index.js',
4848
import: createImport('init', 'browserTracingIntegration', 'replayIntegration'),
4949
gzip: true,
50-
limit: '75.1 KB',
50+
limit: '75.2 KB',
5151
},
5252
{
5353
name: '@sentry/browser (incl. Tracing, Replay) - with treeshaking flags',

packages/core/src/integrations/eventFilters.ts

+6-7
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,12 @@ function _getLastValidUrl(frames: StackFrame[] = []): string | null {
209209

210210
function _getEventFilterUrl(event: Event): string | null {
211211
try {
212-
let frames;
213-
try {
214-
// @ts-expect-error we only care about frames if the whole thing here is defined
215-
frames = event.exception.values[0].stacktrace.frames;
216-
} catch (e) {
217-
// ignore
218-
}
212+
// If there are linked exceptions or exception aggregates we only want to match against the top frame of the "root" (the main exception)
213+
// The root always comes last in linked exceptions
214+
const rootException = [...(event.exception?.values ?? []).reverse()]?.find(
215+
value => value.mechanism?.parent_id === undefined && value.stacktrace?.frames?.length,
216+
);
217+
const frames = rootException?.stacktrace?.frames;
219218
return frames ? _getLastValidUrl(frames) : null;
220219
} catch (oO) {
221220
DEBUG_BUILD && logger.error(`Cannot extract url for event ${getEventDescription(event)}`);

packages/core/test/lib/integrations/eventFilters.test.ts

+111-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ function createEventFiltersEventProcessor(
3838
dsn: PUBLIC_DSN,
3939
...clientOptions,
4040
defaultIntegrations: false,
41-
// eslint-disable-next-line deprecation/deprecation
4241
integrations: [integration],
4342
}),
4443
);
@@ -162,10 +161,91 @@ const EXCEPTION_EVENT_WITH_LINKED_ERRORS: Event = {
162161
{
163162
type: 'ReferenceError',
164163
value: '`tooManyTreats` is not defined',
164+
stacktrace: {
165+
frames: [{ filename: 'https://secondary-error.com/' }],
166+
},
167+
},
168+
{
169+
type: 'TypeError',
170+
value: 'incorrect type given for parameter `chewToy`: Shoe',
171+
stacktrace: {
172+
frames: [{ filename: 'https://main-error.com/' }],
173+
},
174+
},
175+
],
176+
},
177+
};
178+
179+
const EXCEPTION_EVENT_WITH_AGGREGATE_ERRORS: Event = {
180+
exception: {
181+
values: [
182+
{
183+
type: 'ReferenceError',
184+
value: '`tooManyTreats` is not defined',
185+
stacktrace: {
186+
frames: [{ filename: 'https://secondary-error.com/' }],
187+
},
188+
mechanism: {
189+
type: 'generic',
190+
exception_id: 1,
191+
parent_id: 0,
192+
},
165193
},
166194
{
167195
type: 'TypeError',
168196
value: 'incorrect type given for parameter `chewToy`: Shoe',
197+
stacktrace: {
198+
frames: [{ filename: 'https://main-error.com/' }],
199+
},
200+
mechanism: {
201+
type: 'generic',
202+
exception_id: 0,
203+
},
204+
},
205+
],
206+
},
207+
};
208+
209+
const EXCEPTION_EVENT_WITH_LINKED_ERRORS_WITHOUT_STACKTRACE: Event = {
210+
exception: {
211+
values: [
212+
{
213+
type: 'ReferenceError',
214+
value: '`tooManyTreats` is not defined',
215+
stacktrace: {
216+
frames: [{ filename: 'https://main-error.com/' }],
217+
},
218+
},
219+
{
220+
type: 'TypeError',
221+
value: 'incorrect type given for parameter `chewToy`: Shoe',
222+
},
223+
],
224+
},
225+
};
226+
227+
const EXCEPTION_EVENT_WITH_AGGREGATE_ERRORS_WITHOUT_STACKTRACE: Event = {
228+
exception: {
229+
values: [
230+
{
231+
type: 'ReferenceError',
232+
value: '`tooManyTreats` is not defined',
233+
stacktrace: {
234+
frames: [{ filename: 'https://secondary-error.com/' }],
235+
},
236+
mechanism: {
237+
type: 'generic',
238+
exception_id: 1,
239+
parent_id: 0,
240+
},
241+
},
242+
{
243+
type: 'TypeError',
244+
value: 'incorrect type given for parameter `chewToy`: Shoe',
245+
mechanism: {
246+
type: 'generic',
247+
exception_id: 0,
248+
},
169249
},
170250
],
171251
},
@@ -624,6 +704,36 @@ describe.each([
624704
});
625705
expect(eventProcessor(MESSAGE_EVENT_WITH_NATIVE_LAST_FRAME, {})).toBe(null);
626706
});
707+
708+
it('should apply denyUrls to the "root" error of a linked exception', () => {
709+
const eventProcessor = createEventFiltersEventProcessor(integrationFn, {
710+
denyUrls: ['https://main-error.com'],
711+
});
712+
expect(eventProcessor(EXCEPTION_EVENT_WITH_LINKED_ERRORS, {})).toBe(null);
713+
});
714+
715+
it('should apply denyUrls to the "root" error of an aggregate exception', () => {
716+
const eventProcessor = createEventFiltersEventProcessor(integrationFn, {
717+
denyUrls: ['https://main-error.com'],
718+
});
719+
expect(eventProcessor(EXCEPTION_EVENT_WITH_AGGREGATE_ERRORS, {})).toBe(null);
720+
});
721+
722+
it('should apply allowUrls to the "most root" exception in the event if there are exceptions without stacktrace', () => {
723+
const eventProcessor = createEventFiltersEventProcessor(integrationFn, {
724+
allowUrls: ['https://some-error-that-is-not-main-error.com'],
725+
});
726+
expect(eventProcessor(EXCEPTION_EVENT_WITH_LINKED_ERRORS_WITHOUT_STACKTRACE, {})).toBe(null);
727+
});
728+
729+
it('should not apply allowUrls to the event when the "root" exception of an aggregate error doesn\'t have a stacktrace', () => {
730+
const eventProcessor = createEventFiltersEventProcessor(integrationFn, {
731+
allowUrls: ['https://some-error-that-doesnt-match-anything.com'],
732+
});
733+
expect(eventProcessor(EXCEPTION_EVENT_WITH_AGGREGATE_ERRORS_WITHOUT_STACKTRACE, {})).toBe(
734+
EXCEPTION_EVENT_WITH_AGGREGATE_ERRORS_WITHOUT_STACKTRACE,
735+
);
736+
});
627737
});
628738

629739
describe('useless errors', () => {

0 commit comments

Comments
 (0)