Error handling in Angular is not properly managing the custom exception being thrown

I am currently working on an Angular 12 application and I have a requirement to implement a custom ErrorHandler for handling errors globally.

When I receive an error notification from the backend, I subscribe to it in the ToolService using this.notificationService.registerToServerCalls(......). Then, I raise a CustomException which is supposed to be handled by the CustomErrorHandler. However, when the CustomException is thrown, the code does not flow to the CustomErrorHandler.

tool.service.ts

@Injectable()
export class ToolService {
constructor(
        private notificationService: NotificationService,
        @Inject(ErrorHandler) private errorHandler: CustomErrorHandler) {
        this.errorHandler.onUnhandledException$.subscribe({
            next: (error: ErrorDetail[]) => {
                this.dialogService.open(error);
            }
        });
    }


    this.notificationRService.registerToServerCalls<ErrorDetail[]>('Error', (errorDetail: ErrorDetail[]) => {
                this.onError.next(errorDetail);
                throw new CustomException(errorDetail);
            });

notification.service.ts

public registerToServerCalls<T>(clientMethod: string, callback: (data: T) => void): void {
        this.hubConnection.on(clientMethod, callback);
    }

custom-exception.model.ts

export class CustomException extends Error {
    error: ErrorDetail[];

    constructor(error?: ErrorDetail[]) {
        super();
        this.error = error;
    }
}

custom-error-handler.ts

@Injectable()
export class CustomErrorHandler implements ErrorHandler {
  private onUnhandledException = new Subject();
  onUnhandledException$ = this.onUnhandledException.asObservable();
  isErrorHandled = false;

  /**
   * Override the base class error handler to handle the error.
   */
  handleError(errorObj) {
    if (this.isErrorHandled) {
      return;
    }
    
    errorObj = errorObj.rejection ? errorObj.rejection : errorObj; // .rejection is required in case of promise rejections.
    let errorDetails: ErrorDetail[];
    
    errorDetails = errorObj.error;

    this.onUnhandledException.next(errorDetails);
    this.isErrorHandled = true;
  }

}

Answer №1

There seems to be a straightforward solution to this issue, although the reason behind it remains unclear. I encountered a similar problem not too long ago.

The root of the problem lies in Angular using a distinct instance of CustomErrorHandler compared to the one being injected into your service.

A potential fix for this could involve implementing the following on both your error handler and services, but its effectiveness is questionable.

@Injectable({
  providedIn: 'root'
})

In my specific scenario, I resorted to employing a secondary service like this:

export class ErrorMessageService {
    private unhandledException = new Subject();
    unhandledException$ = this.unhandledException.asObservable();

    setMessage(message: string){
        unhandledException.next(message);
    }
}

export class CustomErrorHandler implements ErrorHandler {
    constructor(private errorMessageService: ErrorMessageService)

    handleError(errorObj) {
        this.errorMessageService.setMessage(...)
        ...
        ...
    }
}

export class ToolService {
    constructor(
        private notificationService: NotificationService,
        private errorMessageService: ErrorMessageService) 
    {
        this.errorMessageService.unhandledException$.subscribe({
        next: (error: ErrorDetail[]) => {
            this.dialogService.open(error);
            }
        });
    }
}

As an alternative approach, you could consider merging the ErrorMessageService and ToolService, then injecting the ToolService into your error handler.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for concealing scrollbars across various browsers without compromising functionality

Is there a way to hide the scrollbar functionality on a horizontal scrollbar without using "overflow: hidden"? I need to maintain JS functionality and ensure compatibility with all modern browsers. $j = jQuery.noConflict(); var $panels = $j('#primar ...

Is your Node.js HTTP Request failing to function properly?

I am currently working on creating an HTTP Request function where all requests are directed to the same domain but with different file names. Unfortunately, I am encountering a problem where nothing is being displayed in the console and no data is being r ...

Surfing the web with Internet Explorer means music downloads rather than streaming

My music website functions properly, however I am experiencing issues when accessing it through Internet Explorer. The internet download manager is downloading music from the site without any problems in Chrome and Firefox. Is there a way to prevent or b ...

Step-by-step guide on importing Nano (CouchDB) using Typescript

I am facing difficulty in importing and using nano in my node application. According to the documentation, the JavaScript way is: var nano = require('nano')('http://localhost:5984'); How can I achieve this with TypeScript? I attempt ...

Firestore query is not displaying the expected data, resulting in an empty array being returned

I've encountered an issue where my query is returning an empty array. Despite double-checking for errors and typos in the query, no error messages are popping up. This problem arose while working on a learning project inspired by Firehip's NextJS ...

Sluggish website loading time

Hey there, I'm currently developing a website and I'm facing a major issue with one of my pages loading slowly and experiencing lag. I'm unsure if this is due to the on scroll listeners or the excessive references in my code. Could it possib ...

In Node.js, fast-xml-parse is only returning a single object instead of an array

Currently, I am working on implementing tracking functionality using a specific service that provides responses in XML format. For parsing the XML response, I have opted to utilize the fast-xml-parser package. However, I have encountered an issue: Everyth ...

Unable to retrieve input values from the text fields using JavaScript

In my project, I have created two PHP pages - "doc.php" and "chkval.php". The issue I am facing is that the textfield values are not being captured in the "chkval.php" page using $POST method. An error that I encountered is: Use of undefined constant re ...

Challenges encountered while deploying a NextJS project with TypeScript on Vercel

Encountering an error on Vercel during the build deploy process. The error message says: https://i.stack.imgur.com/Wk0Rw.png Oddly, the command pnpm run build works smoothly on my PC. Both it and the linting work fine. Upon inspecting the code, I noticed ...

Using Angular 2 with Material 2 to create dynamic checkbox bindings

I am currently working on an Angular 2 (2.4.3) application that utilizes Material (2.0.0-beta.1), and I have encountered a challenge with bindings on checkboxes. My goal is to have a checkbox reflect a boolean value in my component and toggle the value wh ...

Creating a scale effect similar to iCloud.com in Angular.JS: A step-by-step guide

Have you checked out the new icloud.com site? There's a cool effect on there that I want to try and recreate for a project I'm working on. When you go to and log in, you'll notice a loading gif followed by the calendar app scaling out to t ...

Troubleshooting Problem with ListItem Alignment in Material UI v0 involving Custom Avatar Component

Material UI version: v0.20.0 I'm facing an issue with aligning the leftAvatar value using the CustomAvatar component, as shown in the attached screenshot. Any assistance would be appreciated. CustomAvatar: The functionality of this component is cond ...

React components are failing to display data as expected

I need to display certain data based on the id provided in the url. When I use console.log() with res.json, I can see the data but I'm unsure how to pass it to the 'articleComponent'. const Articles = () => { const query = (id) => ...

Failure in retrieving values from AngularFire2 Subscribe

I am encountering an issue with the code in my authService constructor( private afAuth: AngularFireAuth, private db: AngularFireDatabase, private router: Router ) { this.authState = afAuth.authState; this.authState.subscribe((use ...

Unable to retrieve data function properties within Vue.Js Component methods

Looking for some help with setting up a welcome message using an input field in Vue.js. I am trying to store the username in a data property called username: ''. However, when I attempt to access it within the methods, I receive an error stating ...

Is it possible to refresh a div on one .aspx page using content from another .aspx page?

Just beginning my journey with asp.net and currently tackling a project that involves two .aspx pages. Events.aspx: This page is where the site admin can update upcoming events and webinars using an available panel to input event title, date, information ...

Unique Text: "Personalized marker/pin for interactive map feature"

Looking to create a custom image map marker/pin with a unique bottom design resembling a union shape using CSS and Vue.js. I've attempted it myself but haven't been able to achieve the exact look as shown in the reference image. Any advice or ass ...

How to dynamically increase vote tallies with React.js

The voting system code below is functioning well, displaying results upon page load. However, I am facing an issue where each user's vote needs to be updated whenever the Get Vote Count button is clicked. In the backend, there is a PHP code snippet ...

How to make sure that an element overflowing its container always starts from the top

My website has a section called <mat-drawer-container>, which contains a list of items called <mat-selection-list>. However, when the number of elements in the list exceeds the display height and scrolling is necessary, the scroll position star ...

Ways to leverage ember.js in a serverless environment

After checking out the example of ember.js on this website (http://todomvc.com/), I decided to clone the project onto my computer. Upon double-clicking the index.html file, the project ran smoothly, just as I had anticipated. However, following the instru ...