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' ;
@@ -80,21 +80,28 @@ function isErrorOrErrorLikeObject(value: unknown): value is Error {
8080 * Implementation of Angular's ErrorHandler provider that can be used as a drop-in replacement for the stock one.
8181 */
8282@Injectable ( { providedIn : 'root' } )
83- class SentryErrorHandler implements AngularErrorHandler {
83+ class SentryErrorHandler implements AngularErrorHandler , OnDestroy {
8484 protected readonly _options : ErrorHandlerOptions ;
8585
86- /* indicates if we already registered our the afterSendEvent handler */
87- private _registeredAfterSendEventHandler ;
86+ /** The cleanup function is executed when the injector is destroyed. */
87+ private _removeAfterSendEventListener ?: VoidFunction ;
8888
8989 public constructor ( @Inject ( 'errorHandlerOptions' ) options ?: ErrorHandlerOptions ) {
90- this . _registeredAfterSendEventHandler = false ;
91-
9290 this . _options = {
9391 logErrors : true ,
9492 ...options ,
9593 } ;
9694 }
9795
96+ /**
97+ * Method executed when the injector is destroyed.
98+ */
99+ public ngOnDestroy ( ) : void {
100+ if ( this . _removeAfterSendEventListener ) {
101+ this . _removeAfterSendEventListener ( ) ;
102+ }
103+ }
104+
98105 /**
99106 * Method called for every value captured through the ErrorHandler
100107 */
@@ -118,17 +125,14 @@ class SentryErrorHandler implements AngularErrorHandler {
118125 if ( this . _options . showDialog ) {
119126 const client = Sentry . getClient ( ) ;
120127
121- if ( client && ! this . _registeredAfterSendEventHandler ) {
122- client . on ( 'afterSendEvent' , ( event : Event ) => {
128+ if ( client && ! this . _removeAfterSendEventListener ) {
129+ this . _removeAfterSendEventListener = client . on ( 'afterSendEvent' , ( event : Event ) => {
123130 if ( ! event . type && event . event_id ) {
124131 runOutsideAngular ( ( ) => {
125132 Sentry . showReportDialog ( { ...this . _options . dialogOptions , eventId : event . event_id ! } ) ;
126133 } ) ;
127134 }
128135 } ) ;
129-
130- // We only want to register this hook once in the lifetime of the error handler
131- this . _registeredAfterSendEventHandler = true ;
132136 } else if ( ! client ) {
133137 runOutsideAngular ( ( ) => {
134138 Sentry . showReportDialog ( { ...this . _options . dialogOptions , eventId } ) ;
0 commit comments