1
1
import { HttpErrorResponse } from '@angular/common/http' ;
2
- import type { ErrorHandler as AngularErrorHandler } from '@angular/core' ;
2
+ import type { ErrorHandler as AngularErrorHandler , OnDestroy } from '@angular/core' ;
3
3
import { Inject , Injectable } from '@angular/core' ;
4
4
import * as Sentry from '@sentry/browser' ;
5
5
import type { ReportDialogOptions } from '@sentry/browser' ;
@@ -80,21 +80,28 @@ function isErrorOrErrorLikeObject(value: unknown): value is Error {
80
80
* Implementation of Angular's ErrorHandler provider that can be used as a drop-in replacement for the stock one.
81
81
*/
82
82
@Injectable ( { providedIn : 'root' } )
83
- class SentryErrorHandler implements AngularErrorHandler {
83
+ class SentryErrorHandler implements AngularErrorHandler , OnDestroy {
84
84
protected readonly _options : ErrorHandlerOptions ;
85
85
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 ;
88
88
89
89
public constructor ( @Inject ( 'errorHandlerOptions' ) options ?: ErrorHandlerOptions ) {
90
- this . _registeredAfterSendEventHandler = false ;
91
-
92
90
this . _options = {
93
91
logErrors : true ,
94
92
...options ,
95
93
} ;
96
94
}
97
95
96
+ /**
97
+ * Method executed when the injector is destroyed.
98
+ */
99
+ public ngOnDestroy ( ) : void {
100
+ if ( this . _removeAfterSendEventListener ) {
101
+ this . _removeAfterSendEventListener ( ) ;
102
+ }
103
+ }
104
+
98
105
/**
99
106
* Method called for every value captured through the ErrorHandler
100
107
*/
@@ -118,17 +125,14 @@ class SentryErrorHandler implements AngularErrorHandler {
118
125
if ( this . _options . showDialog ) {
119
126
const client = Sentry . getClient ( ) ;
120
127
121
- if ( client && ! this . _registeredAfterSendEventHandler ) {
122
- client . on ( 'afterSendEvent' , ( event : Event ) => {
128
+ if ( client && ! this . _removeAfterSendEventListener ) {
129
+ this . _removeAfterSendEventListener = client . on ( 'afterSendEvent' , ( event : Event ) => {
123
130
if ( ! event . type && event . event_id ) {
124
131
runOutsideAngular ( ( ) => {
125
132
Sentry . showReportDialog ( { ...this . _options . dialogOptions , eventId : event . event_id ! } ) ;
126
133
} ) ;
127
134
}
128
135
} ) ;
129
-
130
- // We only want to register this hook once in the lifetime of the error handler
131
- this . _registeredAfterSendEventHandler = true ;
132
136
} else if ( ! client ) {
133
137
runOutsideAngular ( ( ) => {
134
138
Sentry . showReportDialog ( { ...this . _options . dialogOptions , eventId } ) ;
0 commit comments