1
1
import { Backend , logger , Options , SentryError } from '@sentry/core' ;
2
- import { SentryEvent , SentryResponse , Status } from '@sentry/types' ;
2
+ import { SentryEvent , SentryEventHint , SentryResponse , Severity , Status , Transport } from '@sentry/types' ;
3
3
import { isDOMError , isDOMException , isError , isErrorEvent , isPlainObject } from '@sentry/utils/is' ;
4
- import { supportsFetch } from '@sentry/utils/supports' ;
4
+ import { supportsBeacon , supportsFetch } from '@sentry/utils/supports' ;
5
5
import { eventFromPlainObject , eventFromStacktrace , prepareFramesForEvent } from './parsers' ;
6
6
import { computeStackTrace } from './tracekit' ;
7
- import { FetchTransport , XHRTransport } from './transports' ;
7
+ import { BeaconTransport , FetchTransport , XHRTransport } from './transports' ;
8
8
9
9
/**
10
10
* Configuration options for the Sentry Browser SDK.
@@ -37,6 +37,9 @@ export class BrowserBackend implements Backend {
37
37
/** Creates a new browser backend instance. */
38
38
public constructor ( private readonly options : BrowserOptions = { } ) { }
39
39
40
+ /** Cached transport used internally. */
41
+ private transport ?: Transport ;
42
+
40
43
/**
41
44
* @inheritDoc
42
45
*/
@@ -57,7 +60,7 @@ export class BrowserBackend implements Backend {
57
60
/**
58
61
* @inheritDoc
59
62
*/
60
- public async eventFromException ( exception : any , syntheticException : Error | null ) : Promise < SentryEvent > {
63
+ public async eventFromException ( exception : any , hint ?: SentryEventHint ) : Promise < SentryEvent > {
61
64
let event ;
62
65
63
66
if ( isErrorEvent ( exception as ErrorEvent ) && ( exception as ErrorEvent ) . error ) {
@@ -74,16 +77,16 @@ export class BrowserBackend implements Backend {
74
77
const name = ex . name || ( isDOMError ( ex ) ? 'DOMError' : 'DOMException' ) ;
75
78
const message = ex . message ? `${ name } : ${ ex . message } ` : name ;
76
79
77
- event = await this . eventFromMessage ( message , syntheticException ) ;
80
+ event = await this . eventFromMessage ( message , undefined , hint ) ;
78
81
} else if ( isError ( exception as Error ) ) {
79
82
// we have a real Error object, do nothing
80
83
event = eventFromStacktrace ( computeStackTrace ( exception as Error ) ) ;
81
- } else if ( isPlainObject ( exception as { } ) ) {
84
+ } else if ( isPlainObject ( exception as { } ) && hint && hint . syntheticException ) {
82
85
// If it is plain Object, serialize it manually and extract options
83
86
// This will allow us to group events based on top-level keys
84
87
// which is much better than creating new group when any key/value change
85
88
const ex = exception as { } ;
86
- event = eventFromPlainObject ( ex , syntheticException ) ;
89
+ event = eventFromPlainObject ( ex , hint . syntheticException ) ;
87
90
} else {
88
91
// If none of previous checks were valid, then it means that
89
92
// it's not a DOMError/DOMException
@@ -92,11 +95,12 @@ export class BrowserBackend implements Backend {
92
95
// it's not an Error
93
96
// So bail out and capture it as a simple message:
94
97
const ex = exception as string ;
95
- event = await this . eventFromMessage ( ex , syntheticException ) ;
98
+ event = await this . eventFromMessage ( ex , undefined , hint ) ;
96
99
}
97
100
98
101
event = {
99
102
...event ,
103
+ event_id : hint && hint . event_id ,
100
104
exception : {
101
105
...event . exception ,
102
106
mechanism : {
@@ -112,14 +116,16 @@ export class BrowserBackend implements Backend {
112
116
/**
113
117
* @inheritDoc
114
118
*/
115
- public async eventFromMessage ( message : string , syntheticException : Error | null ) : Promise < SentryEvent > {
119
+ public async eventFromMessage ( message : string , level ?: Severity , hint ?: SentryEventHint ) : Promise < SentryEvent > {
116
120
const event : SentryEvent = {
121
+ event_id : hint && hint . event_id ,
117
122
fingerprint : [ message ] ,
123
+ level,
118
124
message,
119
125
} ;
120
126
121
- if ( this . options . attachStacktrace && syntheticException ) {
122
- const stacktrace = computeStackTrace ( syntheticException ) ;
127
+ if ( this . options . attachStacktrace && hint && hint . syntheticException ) {
128
+ const stacktrace = computeStackTrace ( hint . syntheticException ) ;
123
129
const frames = prepareFramesForEvent ( stacktrace . stack ) ;
124
130
event . stacktrace = {
125
131
frames,
@@ -139,15 +145,23 @@ export class BrowserBackend implements Backend {
139
145
return { status : Status . Skipped } ;
140
146
}
141
147
142
- const transportOptions = this . options . transportOptions ? this . options . transportOptions : { dsn : this . options . dsn } ;
143
-
144
- const transport = this . options . transport
145
- ? new this . options . transport ( { dsn : this . options . dsn } )
146
- : supportsFetch ( )
147
- ? new FetchTransport ( transportOptions )
148
- : new XHRTransport ( transportOptions ) ;
148
+ if ( ! this . transport ) {
149
+ const transportOptions = this . options . transportOptions
150
+ ? this . options . transportOptions
151
+ : { dsn : this . options . dsn } ;
152
+
153
+ if ( this . options . transport ) {
154
+ this . transport = new this . options . transport ( { dsn : this . options . dsn } ) ;
155
+ } else if ( supportsBeacon ( ) ) {
156
+ this . transport = new BeaconTransport ( transportOptions ) ;
157
+ } else if ( supportsFetch ( ) ) {
158
+ this . transport = new FetchTransport ( transportOptions ) ;
159
+ } else {
160
+ this . transport = new XHRTransport ( transportOptions ) ;
161
+ }
162
+ }
149
163
150
- return transport . send ( event ) ;
164
+ return this . transport . send ( event ) ;
151
165
}
152
166
153
167
/**
0 commit comments