@@ -53,15 +53,15 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
5353 /** Options passed to the SDK. */
5454 protected readonly _options : O ;
5555
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. */
6057 protected readonly _dsn ?: Dsn ;
6158
6259 /** Array of used integrations. */
6360 protected readonly _integrations : IntegrationIndex ;
6461
62+ /** Is the client still processing a call? */
63+ protected _processing : boolean = false ;
64+
6565 /**
6666 * Initializes this client instance.
6767 *
@@ -84,15 +84,19 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
8484 */
8585 public captureException ( exception : any , hint ?: EventHint , scope ?: Scope ) : string | undefined {
8686 let eventId : string | undefined = hint && hint . event_id ;
87+ this . _processing = true ;
8788
8889 this . _getBackend ( )
8990 . eventFromException ( exception , hint )
9091 . then ( event => this . _processEvent ( event , hint , scope ) )
9192 . 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 ;
9396 } )
9497 . catch ( reason => {
9598 logger . log ( reason ) ;
99+ this . _processing = false ;
96100 } ) ;
97101
98102 return eventId ;
@@ -104,17 +108,22 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
104108 public captureMessage ( message : string , level ?: Severity , hint ?: EventHint , scope ?: Scope ) : string | undefined {
105109 let eventId : string | undefined = hint && hint . event_id ;
106110
111+ this . _processing = true ;
112+
107113 const promisedEvent = isPrimitive ( message )
108114 ? this . _getBackend ( ) . eventFromMessage ( `${ message } ` , level , hint )
109115 : this . _getBackend ( ) . eventFromException ( message , hint ) ;
110116
111117 promisedEvent
112118 . then ( event => this . _processEvent ( event , hint , scope ) )
113119 . 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 ;
115123 } )
116124 . catch ( reason => {
117125 logger . log ( reason ) ;
126+ this . _processing = false ;
118127 } ) ;
119128
120129 return eventId ;
@@ -125,12 +134,17 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
125134 */
126135 public captureEvent ( event : Event , hint ?: EventHint , scope ?: Scope ) : string | undefined {
127136 let eventId : string | undefined = hint && hint . event_id ;
137+ this . _processing = true ;
138+
128139 this . _processEvent ( event , hint , scope )
129140 . 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 ;
131144 } )
132145 . catch ( reason => {
133146 logger . log ( reason ) ;
147+ this . _processing = false ;
134148 } ) ;
135149 return eventId ;
136150 }
@@ -149,6 +163,64 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
149163 return this . _options ;
150164 }
151165
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+
152224 /** Returns the current backend. */
153225 protected _getBackend ( ) : B {
154226 return this . _backend ;
@@ -315,41 +387,4 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
315387 reject ( `beforeSend rejected with ${ e } ` ) ;
316388 } ) ;
317389 }
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- }
355390}
0 commit comments