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' ;
3
3
import { isFunction , isString } from '@sentry/utils/is' ;
4
+ import { logger } from '@sentry/utils/logger' ;
4
5
import { getEventDescription , getGlobalObject , parseUrl } from '@sentry/utils/misc' ;
5
6
import { deserialize , fill } from '@sentry/utils/object' ;
6
7
import { includes , safeJoin } from '@sentry/utils/string' ;
7
8
import { supportsBeacon , supportsHistory , supportsNativeFetch } from '@sentry/utils/supports' ;
8
- import { BrowserOptions } from '../backend ' ;
9
+ import { BrowserClient } from '../client ' ;
9
10
import { breadcrumbEventHandler , keypressEventHandler , wrap } from './helpers' ;
10
11
11
12
const global = getGlobalObject ( ) as Window ;
@@ -21,28 +22,6 @@ export interface SentryWrappedXMLHttpRequest extends XMLHttpRequest {
21
22
} ;
22
23
}
23
24
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
-
46
25
/** JSDoc */
47
26
interface BreadcrumbIntegrations {
48
27
beacon ?: boolean ;
@@ -61,6 +40,11 @@ export class Breadcrumbs implements Integration {
61
40
*/
62
41
public name : string = 'Breadcrumbs' ;
63
42
43
+ /**
44
+ * @inheritDoc
45
+ */
46
+ public static id : string = 'Breadcrumbs' ;
47
+
64
48
/** JSDoc */
65
49
private readonly options : BreadcrumbIntegrations ;
66
50
@@ -81,7 +65,7 @@ export class Breadcrumbs implements Integration {
81
65
}
82
66
83
67
/** JSDoc */
84
- private instrumentBeacon ( options : { filterUrl ?: string } ) : void {
68
+ private instrumentBeacon ( ) : void {
85
69
if ( ! supportsBeacon ( ) ) {
86
70
return ;
87
71
}
@@ -95,11 +79,16 @@ export class Breadcrumbs implements Integration {
95
79
// https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API/Using_the_Beacon_API
96
80
const result = originalBeaconFunction . apply ( this , args ) ;
97
81
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
+ }
103
92
}
104
93
105
94
// What is wrong with you TypeScript...
@@ -113,7 +102,7 @@ export class Breadcrumbs implements Integration {
113
102
breadcrumbData . level = Severity . Error ;
114
103
}
115
104
116
- getCurrentHub ( ) . addBreadcrumb ( breadcrumbData , {
105
+ Breadcrumbs . addBreadcrumb ( breadcrumbData , {
117
106
input : args ,
118
107
result,
119
108
} ) ;
@@ -156,7 +145,7 @@ export class Breadcrumbs implements Integration {
156
145
}
157
146
}
158
147
159
- getCurrentHub ( ) . addBreadcrumb ( breadcrumbData , {
148
+ Breadcrumbs . addBreadcrumb ( breadcrumbData , {
160
149
input : args ,
161
150
level,
162
151
} ) ;
@@ -182,7 +171,7 @@ export class Breadcrumbs implements Integration {
182
171
}
183
172
184
173
/** JSDoc */
185
- private instrumentFetch ( options : { filterUrl ?: string } ) : void {
174
+ private instrumentFetch ( ) : void {
186
175
if ( ! supportsNativeFetch ( ) ) {
187
176
return ;
188
177
}
@@ -208,13 +197,18 @@ export class Breadcrumbs implements Integration {
208
197
method = args [ 1 ] . method ;
209
198
}
210
199
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 ) ;
216
211
}
217
- return originalFetch . apply ( global , args ) ;
218
212
}
219
213
220
214
const fetchData : {
@@ -230,7 +224,7 @@ export class Breadcrumbs implements Integration {
230
224
. apply ( global , args )
231
225
. then ( ( response : Response ) => {
232
226
fetchData . status_code = response . status ;
233
- getCurrentHub ( ) . addBreadcrumb (
227
+ Breadcrumbs . addBreadcrumb (
234
228
{
235
229
category : 'fetch' ,
236
230
data : fetchData ,
@@ -244,7 +238,7 @@ export class Breadcrumbs implements Integration {
244
238
return response ;
245
239
} )
246
240
. catch ( ( error : Error ) => {
247
- getCurrentHub ( ) . addBreadcrumb (
241
+ Breadcrumbs . addBreadcrumb (
248
242
{
249
243
category : 'fetch' ,
250
244
data : fetchData ,
@@ -295,7 +289,7 @@ export class Breadcrumbs implements Integration {
295
289
from = parsedFrom . relative ;
296
290
}
297
291
298
- getCurrentHub ( ) . addBreadcrumb ( {
292
+ Breadcrumbs . addBreadcrumb ( {
299
293
category : 'navigation' ,
300
294
data : {
301
295
from,
@@ -334,7 +328,7 @@ export class Breadcrumbs implements Integration {
334
328
}
335
329
336
330
/** JSDoc */
337
- private instrumentXHR ( options : { filterUrl ?: string } ) : void {
331
+ private instrumentXHR ( ) : void {
338
332
if ( ! ( 'XMLHttpRequest' in global ) ) {
339
333
return ;
340
334
}
@@ -369,11 +363,18 @@ export class Breadcrumbs implements Integration {
369
363
method : args [ 0 ] ,
370
364
url : args [ 1 ] ,
371
365
} ;
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
+ }
376
376
}
377
+
377
378
return originalOpen . apply ( this , args ) ;
378
379
} ,
379
380
) ;
@@ -404,7 +405,7 @@ export class Breadcrumbs implements Integration {
404
405
} catch ( e ) {
405
406
/* do nothing */
406
407
}
407
- getCurrentHub ( ) . addBreadcrumb (
408
+ Breadcrumbs . addBreadcrumb (
408
409
{
409
410
category : 'xhr' ,
410
411
data : xhr . __sentry_xhr__ ,
@@ -447,6 +448,18 @@ export class Breadcrumbs implements Integration {
447
448
} ,
448
449
) ;
449
450
}
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
+
450
463
/**
451
464
* Instrument browser built-ins w/ breadcrumb capturing
452
465
* - Console API
@@ -455,26 +468,45 @@ export class Breadcrumbs implements Integration {
455
468
* - Fetch API
456
469
* - History API
457
470
*/
458
- public install ( options : BrowserOptions = { } ) : void {
459
- const filterUrl = options . dsn && new API ( options . dsn ) . getStoreEndpoint ( ) ;
460
-
471
+ public setupOnce ( ) : void {
461
472
if ( this . options . console ) {
462
473
this . instrumentConsole ( ) ;
463
474
}
464
475
if ( this . options . dom ) {
465
476
this . instrumentDOM ( ) ;
466
477
}
467
478
if ( this . options . xhr ) {
468
- this . instrumentXHR ( { filterUrl } ) ;
479
+ this . instrumentXHR ( ) ;
469
480
}
470
481
if ( this . options . fetch ) {
471
- this . instrumentFetch ( { filterUrl } ) ;
482
+ this . instrumentFetch ( ) ;
472
483
}
473
484
if ( this . options . beacon ) {
474
- this . instrumentBeacon ( { filterUrl } ) ;
485
+ this . instrumentBeacon ( ) ;
475
486
}
476
487
if ( this . options . history ) {
477
488
this . instrumentHistory ( ) ;
478
489
}
479
490
}
480
491
}
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