11import { HttpErrorResponse } from '@angular/common/http' ;
2- import type { ErrorHandler as AngularErrorHandler } from '@angular/core' ;
2+ import type { ErrorHandler as AngularErrorHandler , OnDestroy } from '@angular/core' ;
33import { Inject , Injectable } from '@angular/core' ;
44import * as Sentry from '@sentry/browser' ;
55import type { ReportDialogOptions } from '@sentry/browser' ;
@@ -81,21 +81,28 @@ function isErrorOrErrorLikeObject(value: unknown): value is Error {
8181 * Implementation of Angular's ErrorHandler provider that can be used as a drop-in replacement for the stock one.
8282 */
8383@Injectable ( { providedIn : 'root' } )
84- class SentryErrorHandler implements AngularErrorHandler {
84+ class SentryErrorHandler implements AngularErrorHandler , OnDestroy {
8585 protected readonly _options : ErrorHandlerOptions ;
8686
87- /* indicates if we already registered our the afterSendEvent handler */
88- private _registeredAfterSendEventHandler ;
87+ /** The cleanup function is executed when the injector is destroyed. */
88+ private _removeAfterSendEventListener ?: ( ) => void ;
8989
9090 public constructor ( @Inject ( 'errorHandlerOptions' ) options ?: ErrorHandlerOptions ) {
91- this . _registeredAfterSendEventHandler = false ;
92-
9391 this . _options = {
9492 logErrors : true ,
9593 ...options ,
9694 } ;
9795 }
9896
97+ /**
98+ * Method executed when the injector is destroyed.
99+ */
100+ public ngOnDestroy ( ) : void {
101+ if ( this . _removeAfterSendEventListener ) {
102+ this . _removeAfterSendEventListener ( ) ;
103+ }
104+ }
105+
99106 /**
100107 * Method called for every value captured through the ErrorHandler
101108 */
@@ -119,17 +126,14 @@ class SentryErrorHandler implements AngularErrorHandler {
119126 if ( this . _options . showDialog ) {
120127 const client = Sentry . getClient ( ) ;
121128
122- if ( client && ! this . _registeredAfterSendEventHandler ) {
123- client . on ( 'afterSendEvent' , ( event : Event ) => {
129+ if ( client && ! this . _removeAfterSendEventListener ) {
130+ this . _removeAfterSendEventListener = client . on ( 'afterSendEvent' , ( event : Event ) => {
124131 if ( ! event . type && event . event_id ) {
125132 runOutsideAngular ( ( ) => {
126- Sentry . showReportDialog ( { ...this . _options . dialogOptions , eventId : event . event_id ! } ) ;
133+ Sentry . showReportDialog ( { ...this . _options . dialogOptions , eventId : event . event_id } ) ;
127134 } ) ;
128135 }
129136 } ) ;
130-
131- // We only want to register this hook once in the lifetime of the error handler
132- this . _registeredAfterSendEventHandler = true ;
133137 } else if ( ! client ) {
134138 runOutsideAngular ( ( ) => {
135139 Sentry . showReportDialog ( { ...this . _options . dialogOptions , eventId } ) ;
0 commit comments