1- import { API , getCurrentHub , logger } from '@sentry/core' ;
2- import { Integration , Severity } from '@sentry/types' ;
1+ import { API , getCurrentHub } from '@sentry/core' ;
2+ import { Breadcrumb , Integration , SentryBreadcrumbHint , Severity } from '@sentry/types' ;
33import { isFunction , isString } from '@sentry/utils/is' ;
4+ import { logger } from '@sentry/utils/logger' ;
45import { getEventDescription , getGlobalObject , parseUrl } from '@sentry/utils/misc' ;
56import { deserialize , fill } from '@sentry/utils/object' ;
67import { includes , safeJoin } from '@sentry/utils/string' ;
78import { supportsBeacon , supportsHistory , supportsNativeFetch } from '@sentry/utils/supports' ;
8- import { BrowserOptions } from '../backend ' ;
9+ import { BrowserClient } from '../client ' ;
910import { breadcrumbEventHandler , keypressEventHandler , wrap } from './helpers' ;
1011
1112const global = getGlobalObject ( ) as Window ;
@@ -21,28 +22,6 @@ export interface SentryWrappedXMLHttpRequest extends XMLHttpRequest {
2122 } ;
2223}
2324
24- /** JSDoc */
25- function addSentryBreadcrumb ( serializedData : string ) : void {
26- // There's always something that can go wrong with deserialization...
27- try {
28- const event : { [ key : string ] : any } = deserialize ( serializedData ) ;
29-
30- getCurrentHub ( ) . addBreadcrumb (
31- {
32- category : 'sentry' ,
33- event_id : event . event_id ,
34- level : event . level || Severity . fromString ( 'error' ) ,
35- message : getEventDescription ( event ) ,
36- } ,
37- {
38- event,
39- } ,
40- ) ;
41- } catch ( _oO ) {
42- logger . error ( 'Error while adding sentry type breadcrumb' ) ;
43- }
44- }
45-
4625/** JSDoc */
4726interface BreadcrumbIntegrations {
4827 beacon ?: boolean ;
@@ -61,6 +40,11 @@ export class Breadcrumbs implements Integration {
6140 */
6241 public name : string = 'Breadcrumbs' ;
6342
43+ /**
44+ * @inheritDoc
45+ */
46+ public static id : string = 'Breadcrumbs' ;
47+
6448 /** JSDoc */
6549 private readonly options : BreadcrumbIntegrations ;
6650
@@ -81,7 +65,7 @@ export class Breadcrumbs implements Integration {
8165 }
8266
8367 /** JSDoc */
84- private instrumentBeacon ( options : { filterUrl ?: string } ) : void {
68+ private instrumentBeacon ( ) : void {
8569 if ( ! supportsBeacon ( ) ) {
8670 return ;
8771 }
@@ -95,11 +79,16 @@ export class Breadcrumbs implements Integration {
9579 // https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API/Using_the_Beacon_API
9680 const result = originalBeaconFunction . apply ( this , args ) ;
9781
98- // if Sentry key appears in URL, don't capture it as a request
99- // but rather as our own 'sentry' type breadcrumb
100- if ( options . filterUrl && includes ( url , options . filterUrl ) ) {
101- addSentryBreadcrumb ( data ) ;
102- return result ;
82+ const client = getCurrentHub ( ) . getClient ( ) as BrowserClient ;
83+ const dsn = client && client . getDsn ( ) ;
84+ if ( dsn ) {
85+ const filterUrl = new API ( dsn ) . getStoreEndpoint ( ) ;
86+ // if Sentry key appears in URL, don't capture it as a request
87+ // but rather as our own 'sentry' type breadcrumb
88+ if ( filterUrl && includes ( url , filterUrl ) ) {
89+ addSentryBreadcrumb ( data ) ;
90+ return result ;
91+ }
10392 }
10493
10594 // What is wrong with you TypeScript...
@@ -113,7 +102,7 @@ export class Breadcrumbs implements Integration {
113102 breadcrumbData . level = Severity . Error ;
114103 }
115104
116- getCurrentHub ( ) . addBreadcrumb ( breadcrumbData , {
105+ Breadcrumbs . addBreadcrumb ( breadcrumbData , {
117106 input : args ,
118107 result,
119108 } ) ;
@@ -156,7 +145,7 @@ export class Breadcrumbs implements Integration {
156145 }
157146 }
158147
159- getCurrentHub ( ) . addBreadcrumb ( breadcrumbData , {
148+ Breadcrumbs . addBreadcrumb ( breadcrumbData , {
160149 input : args ,
161150 level,
162151 } ) ;
@@ -182,7 +171,7 @@ export class Breadcrumbs implements Integration {
182171 }
183172
184173 /** JSDoc */
185- private instrumentFetch ( options : { filterUrl ?: string } ) : void {
174+ private instrumentFetch ( ) : void {
186175 if ( ! supportsNativeFetch ( ) ) {
187176 return ;
188177 }
@@ -208,13 +197,18 @@ export class Breadcrumbs implements Integration {
208197 method = args [ 1 ] . method ;
209198 }
210199
211- // if Sentry key appears in URL, don't capture it as a request
212- // but rather as our own 'sentry' type breadcrumb
213- if ( options . filterUrl && includes ( url , options . filterUrl ) ) {
214- if ( method === 'POST' && args [ 1 ] && args [ 1 ] . body ) {
215- addSentryBreadcrumb ( args [ 1 ] . body ) ;
200+ const client = getCurrentHub ( ) . getClient ( ) as BrowserClient ;
201+ const dsn = client && client . getDsn ( ) ;
202+ if ( dsn ) {
203+ const filterUrl = new API ( dsn ) . getStoreEndpoint ( ) ;
204+ // if Sentry key appears in URL, don't capture it as a request
205+ // but rather as our own 'sentry' type breadcrumb
206+ if ( filterUrl && includes ( url , filterUrl ) ) {
207+ if ( method === 'POST' && args [ 1 ] && args [ 1 ] . body ) {
208+ addSentryBreadcrumb ( args [ 1 ] . body ) ;
209+ }
210+ return originalFetch . apply ( global , args ) ;
216211 }
217- return originalFetch . apply ( global , args ) ;
218212 }
219213
220214 const fetchData : {
@@ -230,7 +224,7 @@ export class Breadcrumbs implements Integration {
230224 . apply ( global , args )
231225 . then ( ( response : Response ) => {
232226 fetchData . status_code = response . status ;
233- getCurrentHub ( ) . addBreadcrumb (
227+ Breadcrumbs . addBreadcrumb (
234228 {
235229 category : 'fetch' ,
236230 data : fetchData ,
@@ -244,7 +238,7 @@ export class Breadcrumbs implements Integration {
244238 return response ;
245239 } )
246240 . catch ( ( error : Error ) => {
247- getCurrentHub ( ) . addBreadcrumb (
241+ Breadcrumbs . addBreadcrumb (
248242 {
249243 category : 'fetch' ,
250244 data : fetchData ,
@@ -295,7 +289,7 @@ export class Breadcrumbs implements Integration {
295289 from = parsedFrom . relative ;
296290 }
297291
298- getCurrentHub ( ) . addBreadcrumb ( {
292+ Breadcrumbs . addBreadcrumb ( {
299293 category : 'navigation' ,
300294 data : {
301295 from,
@@ -334,7 +328,7 @@ export class Breadcrumbs implements Integration {
334328 }
335329
336330 /** JSDoc */
337- private instrumentXHR ( options : { filterUrl ?: string } ) : void {
331+ private instrumentXHR ( ) : void {
338332 if ( ! ( 'XMLHttpRequest' in global ) ) {
339333 return ;
340334 }
@@ -369,11 +363,18 @@ export class Breadcrumbs implements Integration {
369363 method : args [ 0 ] ,
370364 url : args [ 1 ] ,
371365 } ;
372- // if Sentry key appears in URL, don't capture it as a request
373- // but rather as our own 'sentry' type breadcrumb
374- if ( isString ( url ) && ( options . filterUrl && includes ( url , options . filterUrl ) ) ) {
375- this . __sentry_own_request__ = true ;
366+
367+ const client = getCurrentHub ( ) . getClient ( ) as BrowserClient ;
368+ const dsn = client && client . getDsn ( ) ;
369+ if ( dsn ) {
370+ const filterUrl = new API ( dsn ) . getStoreEndpoint ( ) ;
371+ // if Sentry key appears in URL, don't capture it as a request
372+ // but rather as our own 'sentry' type breadcrumb
373+ if ( isString ( url ) && ( filterUrl && includes ( url , filterUrl ) ) ) {
374+ this . __sentry_own_request__ = true ;
375+ }
376376 }
377+
377378 return originalOpen . apply ( this , args ) ;
378379 } ,
379380 ) ;
@@ -404,7 +405,7 @@ export class Breadcrumbs implements Integration {
404405 } catch ( e ) {
405406 /* do nothing */
406407 }
407- getCurrentHub ( ) . addBreadcrumb (
408+ Breadcrumbs . addBreadcrumb (
408409 {
409410 category : 'xhr' ,
410411 data : xhr . __sentry_xhr__ ,
@@ -447,6 +448,18 @@ export class Breadcrumbs implements Integration {
447448 } ,
448449 ) ;
449450 }
451+
452+ /**
453+ * Helper that checks if integration is enabled on the client.
454+ * @param breadcrumb Breadcrumb
455+ * @param hint SentryBreadcrumbHint
456+ */
457+ public static addBreadcrumb ( breadcrumb : Breadcrumb , hint ?: SentryBreadcrumbHint ) : void {
458+ if ( getCurrentHub ( ) . getIntegration ( Breadcrumbs ) ) {
459+ getCurrentHub ( ) . addBreadcrumb ( breadcrumb , hint ) ;
460+ }
461+ }
462+
450463 /**
451464 * Instrument browser built-ins w/ breadcrumb capturing
452465 * - Console API
@@ -455,26 +468,45 @@ export class Breadcrumbs implements Integration {
455468 * - Fetch API
456469 * - History API
457470 */
458- public install ( options : BrowserOptions = { } ) : void {
459- const filterUrl = options . dsn && new API ( options . dsn ) . getStoreEndpoint ( ) ;
460-
471+ public setupOnce ( ) : void {
461472 if ( this . options . console ) {
462473 this . instrumentConsole ( ) ;
463474 }
464475 if ( this . options . dom ) {
465476 this . instrumentDOM ( ) ;
466477 }
467478 if ( this . options . xhr ) {
468- this . instrumentXHR ( { filterUrl } ) ;
479+ this . instrumentXHR ( ) ;
469480 }
470481 if ( this . options . fetch ) {
471- this . instrumentFetch ( { filterUrl } ) ;
482+ this . instrumentFetch ( ) ;
472483 }
473484 if ( this . options . beacon ) {
474- this . instrumentBeacon ( { filterUrl } ) ;
485+ this . instrumentBeacon ( ) ;
475486 }
476487 if ( this . options . history ) {
477488 this . instrumentHistory ( ) ;
478489 }
479490 }
480491}
492+
493+ /** JSDoc */
494+ function addSentryBreadcrumb ( serializedData : string ) : void {
495+ // There's always something that can go wrong with deserialization...
496+ try {
497+ const event : { [ key : string ] : any } = deserialize ( serializedData ) ;
498+ Breadcrumbs . addBreadcrumb (
499+ {
500+ category : 'sentry' ,
501+ event_id : event . event_id ,
502+ level : event . level || Severity . fromString ( 'error' ) ,
503+ message : getEventDescription ( event ) ,
504+ } ,
505+ {
506+ event,
507+ } ,
508+ ) ;
509+ } catch ( _oO ) {
510+ logger . error ( 'Error while adding sentry type breadcrumb' ) ;
511+ }
512+ }
0 commit comments