Hone logo
Hone
Problems

Robust Angular Error Handling with a Global Error Handler

This challenge focuses on implementing a robust and centralized error handling mechanism within an Angular application. Effectively managing errors is crucial for providing a user-friendly experience, aiding in debugging, and maintaining application stability. You will create a global error handler that intercepts and processes uncaught exceptions.

Problem Description

Your task is to implement a global error handler in an Angular application. This handler should be responsible for catching all uncaught exceptions that occur during the application's lifecycle. When an error is caught, it should be logged to the console and, optionally, displayed to the user in a user-friendly manner.

Key Requirements:

  1. Create a Global Error Handler Service: Develop an Angular service that implements the ErrorHandler interface.
  2. Intercept Errors: This service must override the handleError method to catch all uncaught exceptions.
  3. Log Errors: Inside handleError, log the error details (e.g., error message, stack trace) to the browser's developer console.
  4. Provide User Feedback (Optional but Recommended): Implement a basic mechanism to inform the user that an error has occurred. This could be a simple alert() or a more sophisticated notification component.
  5. Register the Error Handler: Configure your Angular application to use your custom global error handler.

Expected Behavior:

  • When any unhandled error occurs in your Angular application (e.g., a runtime exception in a component, a failed HTTP request not caught by a component-level catchError), your global error handler should be invoked.
  • The error details should appear in the browser's developer console.
  • The user should receive some form of notification about the error.

Edge Cases to Consider:

  • Errors occurring during initial application bootstrapping.
  • Errors originating from asynchronous operations (e.g., Promises, Observables).
  • The error object itself might be null or undefined.

Examples

Example 1: Runtime Component Error

Scenario: A component attempts to access a property of an undefined object.

// In a component:
export class MyComponent implements OnInit {
  data: any;

  ngOnInit() {
    console.log(this.data.nonExistentProperty); // This will throw an error
  }
}

Expected Output (Console):

Error: Cannot read properties of undefined (reading 'nonExistentProperty')
Error: ... (stack trace)

Expected Output (User Feedback):

A user-facing message like "An unexpected error occurred. Please try again later." (or similar, depending on implementation).

Explanation: The runtime error in MyComponent is not caught by any local try...catch block or catchError operator. Therefore, the global error handler intercepts it, logs it to the console, and displays a user-friendly message.

Example 2: HTTP Request Error (Uncaught)

Scenario: A service makes an HTTP request that fails (e.g., 404 Not Found) and the error is not handled by the component or service making the call.

// In a service:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class DataService {
  constructor(private http: HttpClient) {}

  getData() {
    return this.http.get('/api/non-existent-endpoint'); // This will likely throw an error
  }
}

// In a component:
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';

@Component({ ... })
export class DataDisplayComponent implements OnInit {
  constructor(private dataService: DataService) {}

  ngOnInit() {
    this.dataService.getData().subscribe(); // No error handling here
  }
}

Expected Output (Console):

Error: Http failure response for /api/non-existent-endpoint: 404 Not Found
Error: ... (stack trace)

Expected Output (User Feedback):

A user-facing message like "An unexpected error occurred. Please try again later."

Explanation: The HTTP request fails, and since the component subscribing to the observable doesn't have a catchError or other error handling in place, the unhandled error propagates to the global error handler.

Constraints

  • The solution must be written in TypeScript.
  • The core implementation should reside within an Angular service.
  • The error handler must be registered as a provider in your Angular application's module.
  • The logging to the console should include at least the error message. A stack trace is highly recommended.
  • For the user feedback, a simple alert() is acceptable for this challenge, but using Angular's ToastrModule or a custom notification service is a more production-ready approach.

Notes

  • Consider how you might structure your error messages to be informative for developers while remaining understandable or at least non-alarming for end-users.
  • Think about how you can differentiate between different types of errors (e.g., network errors vs. application logic errors) for more targeted handling.
  • The Angular ErrorHandler interface provides the ngErrorHandler symbol for injection.
  • When logging, consider using console.error() for clearer distinction in the console output.
Loading editor...
typescript