Skip to content

Commit b60060d

Browse files
committed
browser: Filter out our own requests from breadcrumb integrations
1 parent 3b51e30 commit b60060d

File tree

1 file changed

+36
-17
lines changed

1 file changed

+36
-17
lines changed

packages/browser/src/integrations/breadcrumbs.ts

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import { DSN } from '@sentry/core';
12
import { getCurrentHub } from '@sentry/hub';
23
import { Integration, Severity } from '@sentry/types';
34
import { isFunction, isString } from '@sentry/utils/is';
45
import { getGlobalObject, parseUrl } from '@sentry/utils/misc';
56
import { fill } from '@sentry/utils/object';
67
import { safeJoin } from '@sentry/utils/string';
78
import { supportsFetch, supportsHistory } from '@sentry/utils/supports';
9+
import { BrowserOptions } from '../backend';
810
import { breadcrumbEventHandler, keypressEventHandler, wrap } from './helpers';
911

1012
const global = getGlobalObject() as Window;
@@ -36,7 +38,7 @@ export class Breadcrumbs implements Integration {
3638
* @inheritDoc
3739
*/
3840
public constructor(
39-
private readonly options: {
41+
private readonly config: {
4042
console?: boolean;
4143
dom?: boolean;
4244
fetch?: boolean;
@@ -109,7 +111,7 @@ export class Breadcrumbs implements Integration {
109111
}
110112

111113
/** JSDoc */
112-
private instrumentFetch(): void {
114+
private instrumentFetch(options: { filterUrl?: string }): void {
113115
if (!supportsFetch()) {
114116
return;
115117
}
@@ -131,6 +133,11 @@ export class Breadcrumbs implements Integration {
131133
url = String(fetchInput);
132134
}
133135

136+
// if Sentry key appears in URL, don't capture, as it's our own request
137+
if (options.filterUrl && url.includes(options.filterUrl)) {
138+
return originalFetch.apply(global, args);
139+
}
140+
134141
if (args[1] && args[1].method) {
135142
method = args[1].method;
136143
}
@@ -178,7 +185,12 @@ export class Breadcrumbs implements Integration {
178185
const captureUrlChange = (from: string | undefined, to: string | undefined): void => {
179186
const parsedLoc = parseUrl(global.location.href);
180187
const parsedTo = parseUrl(to as string);
181-
const parsedFrom = parseUrl(from as string);
188+
let parsedFrom = parseUrl(from as string);
189+
190+
// Initial pushState doesn't provide `from` information
191+
if (!parsedFrom.path) {
192+
parsedFrom = parsedLoc;
193+
}
182194

183195
// because onpopstate only tells you the "new" (to) value of location.href, and
184196
// not the previous (from) value, we need to track the value of the current URL
@@ -211,30 +223,30 @@ export class Breadcrumbs implements Integration {
211223
const currentHref = global.location.href;
212224
captureUrlChange(lastHref, currentHref);
213225
if (oldOnPopState) {
214-
return oldOnPopState.apply(global, args);
226+
return oldOnPopState.apply(this, args);
215227
}
216228
};
217229

218230
/** JSDoc */
219231
function historyReplacementFunction(originalHistoryFunction: () => void): () => void {
220232
// note history.pushState.length is 0; intentionally not declaring
221233
// params to preserve 0 arity
222-
return function(...args: any[]): void {
234+
return function(this: History, ...args: any[]): void {
223235
const url = args.length > 2 ? args[2] : undefined;
224236
// url argument is optional
225237
if (url) {
226238
// coerce to string (this is what pushState does)
227239
captureUrlChange(lastHref, String(url));
228240
}
229-
return originalHistoryFunction.apply(global, ...args);
241+
return originalHistoryFunction.apply(this, args);
230242
};
231243
}
232244

233245
fill(global.history, 'pushState', historyReplacementFunction);
234246
fill(global.history, 'replaceState', historyReplacementFunction);
235247
}
236248
/** JSDoc */
237-
private instrumentXHR(): void {
249+
private instrumentXHR(options: { filterUrl?: string }): void {
238250
if (!('XMLHttpRequest' in global)) {
239251
return;
240252
}
@@ -250,6 +262,7 @@ export class Breadcrumbs implements Integration {
250262
function: prop,
251263
handler: (original && original.name) || '<anonymous>',
252264
},
265+
handled: true,
253266
type: 'instrument',
254267
},
255268
}),
@@ -263,7 +276,9 @@ export class Breadcrumbs implements Integration {
263276
'open',
264277
originalOpen =>
265278
function(this: SentryWrappedXMLHttpRequest, ...args: any[]): void {
266-
if (isString(args[1])) {
279+
const url = args[1];
280+
// if Sentry key appears in URL, don't capture, as it's our own request
281+
if (isString(url) && (options.filterUrl && !url.includes(options.filterUrl))) {
267282
this.__sentry_xhr__ = {
268283
method: args[0],
269284
url: args[1],
@@ -312,6 +327,7 @@ export class Breadcrumbs implements Integration {
312327
function: 'onreadystatechange',
313328
handler: (original && original.name) || '<anonymous>',
314329
},
330+
handled: true,
315331
type: 'instrument',
316332
},
317333
},
@@ -323,7 +339,7 @@ export class Breadcrumbs implements Integration {
323339
// are free to set our own and capture the breadcrumb
324340
xhr.onreadystatechange = onreadystatechangeHandler;
325341
}
326-
return originalSend.apply(XMLHttpRequest, args);
342+
return originalSend.apply(this, args);
327343
},
328344
);
329345
}
@@ -337,20 +353,23 @@ export class Breadcrumbs implements Integration {
337353
*
338354
* Can be disabled or individually configured via the `autoBreadcrumbs` config option
339355
*/
340-
public install(): void {
341-
if (this.options.console) {
356+
public install(options: BrowserOptions = {}): void {
357+
// TODO: Use API provider instead of raw `new DSN`
358+
const filterUrl = options.dsn && new DSN(options.dsn).user;
359+
360+
if (this.config.console) {
342361
this.instrumentConsole();
343362
}
344-
if (this.options.dom) {
363+
if (this.config.dom) {
345364
this.instrumentDOM();
346365
}
347-
if (this.options.xhr) {
348-
this.instrumentXHR();
366+
if (this.config.xhr) {
367+
this.instrumentXHR({ filterUrl });
349368
}
350-
if (this.options.fetch) {
351-
this.instrumentFetch();
369+
if (this.config.fetch) {
370+
this.instrumentFetch({ filterUrl });
352371
}
353-
if (this.options.history) {
372+
if (this.config.history) {
354373
this.instrumentHistory();
355374
}
356375
}

0 commit comments

Comments
 (0)