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