Skip to content

Commit

Permalink
fix(angular): remove afterSendEvent listener once root injector is …
Browse files Browse the repository at this point in the history
…destroyed

In this commit, we added cleanup logic to handle the removal of `afterSendEvent`,
which is set up within the Angular error handler. This fixes memory leaks that occur
when the event is still being handled after the root view is removed.
  • Loading branch information
arturovt committed Jul 5, 2024
1 parent a2dcb28 commit 1c1690e
Showing 1 changed file with 11 additions and 3 deletions.
14 changes: 11 additions & 3 deletions packages/angular/src/errorhandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { HttpErrorResponse } from '@angular/common/http';
import type { ErrorHandler as AngularErrorHandler } from '@angular/core';
import type { ErrorHandler as AngularErrorHandler, OnDestroy } from '@angular/core';
import { Inject, Injectable } from '@angular/core';
import * as Sentry from '@sentry/browser';
import type { ReportDialogOptions } from '@sentry/browser';
Expand Down Expand Up @@ -80,12 +80,14 @@ function isErrorOrErrorLikeObject(value: unknown): value is Error {
* Implementation of Angular's ErrorHandler provider that can be used as a drop-in replacement for the stock one.
*/
@Injectable({ providedIn: 'root' })
class SentryErrorHandler implements AngularErrorHandler {
class SentryErrorHandler implements AngularErrorHandler, OnDestroy {
protected readonly _options: ErrorHandlerOptions;

/* indicates if we already registered our the afterSendEvent handler */
private _registeredAfterSendEventHandler;

private _removeAfterSendEventListener: VoidFunction | null = null;

public constructor(@Inject('errorHandlerOptions') options?: ErrorHandlerOptions) {
this._registeredAfterSendEventHandler = false;

Expand All @@ -95,6 +97,12 @@ class SentryErrorHandler implements AngularErrorHandler {
};
}

public ngOnDestroy(): void {
if (this._removeAfterSendEventListener) {
this._removeAfterSendEventListener();
}
}

/**
* Method called for every value captured through the ErrorHandler
*/
Expand All @@ -119,7 +127,7 @@ class SentryErrorHandler implements AngularErrorHandler {
const client = Sentry.getClient();

if (client && !this._registeredAfterSendEventHandler) {
client.on('afterSendEvent', (event: Event) => {
this._removeAfterSendEventListener = client.on('afterSendEvent', (event: Event) => {
if (!event.type && event.event_id) {
runOutsideAngular(() => {
Sentry.showReportDialog({ ...this._options.dialogOptions, eventId: event.event_id! });
Expand Down

0 comments on commit 1c1690e

Please sign in to comment.