@@ -53,15 +53,15 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
53
53
/** Options passed to the SDK. */
54
54
protected readonly _options : O ;
55
55
56
- /**
57
- * The client Dsn, if specified in options. Without this Dsn, the SDK will be
58
- * disabled.
59
- */
56
+ /** The client Dsn, if specified in options. Without this Dsn, the SDK will be disabled. */
60
57
protected readonly _dsn ?: Dsn ;
61
58
62
59
/** Array of used integrations. */
63
60
protected readonly _integrations : IntegrationIndex ;
64
61
62
+ /** Is the client still processing a call? */
63
+ protected _processing : boolean = false ;
64
+
65
65
/**
66
66
* Initializes this client instance.
67
67
*
@@ -84,15 +84,19 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
84
84
*/
85
85
public captureException ( exception : any , hint ?: EventHint , scope ?: Scope ) : string | undefined {
86
86
let eventId : string | undefined = hint && hint . event_id ;
87
+ this . _processing = true ;
87
88
88
89
this . _getBackend ( )
89
90
. eventFromException ( exception , hint )
90
91
. then ( event => this . _processEvent ( event , hint , scope ) )
91
92
. then ( finalEvent => {
92
- eventId = finalEvent . event_id ;
93
+ // We need to check for finalEvent in case beforeSend returned null
94
+ eventId = finalEvent && finalEvent . event_id ;
95
+ this . _processing = false ;
93
96
} )
94
97
. catch ( reason => {
95
98
logger . log ( reason ) ;
99
+ this . _processing = false ;
96
100
} ) ;
97
101
98
102
return eventId ;
@@ -104,17 +108,22 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
104
108
public captureMessage ( message : string , level ?: Severity , hint ?: EventHint , scope ?: Scope ) : string | undefined {
105
109
let eventId : string | undefined = hint && hint . event_id ;
106
110
111
+ this . _processing = true ;
112
+
107
113
const promisedEvent = isPrimitive ( message )
108
114
? this . _getBackend ( ) . eventFromMessage ( `${ message } ` , level , hint )
109
115
: this . _getBackend ( ) . eventFromException ( message , hint ) ;
110
116
111
117
promisedEvent
112
118
. then ( event => this . _processEvent ( event , hint , scope ) )
113
119
. then ( finalEvent => {
114
- eventId = finalEvent . event_id ;
120
+ // We need to check for finalEvent in case beforeSend returned null
121
+ eventId = finalEvent && finalEvent . event_id ;
122
+ this . _processing = false ;
115
123
} )
116
124
. catch ( reason => {
117
125
logger . log ( reason ) ;
126
+ this . _processing = false ;
118
127
} ) ;
119
128
120
129
return eventId ;
@@ -125,12 +134,17 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
125
134
*/
126
135
public captureEvent ( event : Event , hint ?: EventHint , scope ?: Scope ) : string | undefined {
127
136
let eventId : string | undefined = hint && hint . event_id ;
137
+ this . _processing = true ;
138
+
128
139
this . _processEvent ( event , hint , scope )
129
140
. then ( finalEvent => {
130
- eventId = finalEvent . event_id ;
141
+ // We need to check for finalEvent in case beforeSend returned null
142
+ eventId = finalEvent && finalEvent . event_id ;
143
+ this . _processing = false ;
131
144
} )
132
145
. catch ( reason => {
133
146
logger . log ( reason ) ;
147
+ this . _processing = false ;
134
148
} ) ;
135
149
return eventId ;
136
150
}
@@ -149,6 +163,64 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
149
163
return this . _options ;
150
164
}
151
165
166
+ /**
167
+ * @inheritDoc
168
+ */
169
+ public async flush ( timeout ?: number ) : Promise < boolean > {
170
+ return ( await Promise . all ( [
171
+ this . _getBackend ( )
172
+ . getTransport ( )
173
+ . close ( timeout ) ,
174
+ this . _isClientProcessing ( ) ,
175
+ ] ) ) . reduce ( ( prev , current ) => prev && current ) ;
176
+ }
177
+
178
+ /**
179
+ * @inheritDoc
180
+ */
181
+ public async close ( timeout ?: number ) : Promise < boolean > {
182
+ return this . flush ( timeout ) . finally ( ( ) => {
183
+ this . getOptions ( ) . enabled = false ;
184
+ } ) ;
185
+ }
186
+
187
+ /**
188
+ * @inheritDoc
189
+ */
190
+ public getIntegrations ( ) : IntegrationIndex {
191
+ return this . _integrations || { } ;
192
+ }
193
+
194
+ /**
195
+ * @inheritDoc
196
+ */
197
+ public getIntegration < T extends Integration > ( integration : IntegrationClass < T > ) : T | null {
198
+ try {
199
+ return ( this . _integrations [ integration . id ] as T ) || null ;
200
+ } catch ( _oO ) {
201
+ logger . warn ( `Cannot retrieve integration ${ integration . id } from the current Client` ) ;
202
+ return null ;
203
+ }
204
+ }
205
+
206
+ /** Waits for the client to be done with processing. */
207
+ protected async _isClientProcessing ( counter : number = 0 ) : Promise < boolean > {
208
+ return new Promise < boolean > ( resolve => {
209
+ if ( this . _processing ) {
210
+ // Safeguard in case of endless recursion
211
+ if ( counter >= 10 ) {
212
+ resolve ( false ) ;
213
+ } else {
214
+ setTimeout ( async ( ) => {
215
+ resolve ( await this . _isClientProcessing ( counter + 1 ) ) ;
216
+ } , 10 ) ;
217
+ }
218
+ } else {
219
+ resolve ( true ) ;
220
+ }
221
+ } ) ;
222
+ }
223
+
152
224
/** Returns the current backend. */
153
225
protected _getBackend ( ) : B {
154
226
return this . _backend ;
@@ -315,41 +387,4 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
315
387
reject ( `beforeSend rejected with ${ e } ` ) ;
316
388
} ) ;
317
389
}
318
-
319
- /**
320
- * @inheritDoc
321
- */
322
- public async flush ( timeout ?: number ) : Promise < boolean > {
323
- return this . _getBackend ( )
324
- . getTransport ( )
325
- . close ( timeout ) ;
326
- }
327
-
328
- /**
329
- * @inheritDoc
330
- */
331
- public async close ( timeout ?: number ) : Promise < boolean > {
332
- return this . flush ( timeout ) . finally ( ( ) => {
333
- this . getOptions ( ) . enabled = false ;
334
- } ) ;
335
- }
336
-
337
- /**
338
- * @inheritDoc
339
- */
340
- public getIntegrations ( ) : IntegrationIndex {
341
- return this . _integrations || { } ;
342
- }
343
-
344
- /**
345
- * @inheritDoc
346
- */
347
- public getIntegration < T extends Integration > ( integration : IntegrationClass < T > ) : T | null {
348
- try {
349
- return ( this . _integrations [ integration . id ] as T ) || null ;
350
- } catch ( _oO ) {
351
- logger . warn ( `Cannot retrieve integration ${ integration . id } from the current Client` ) ;
352
- return null ;
353
- }
354
- }
355
390
}
0 commit comments