Angular routes uncaught errors to a global ErrorHandler, which logs to the console by default. Replacing it lets you report errors to a monitoring service and show a safe message, but a global handler is a last resort: expected failures such as a failed HTTP call belong closer to the code that can recover.
Before you start
You should be comfortable with dependency injection and HTTP error handling. This article covers the global handler and its boundaries.
Step-by-step walkthrough
Step 1: Implement a custom ErrorHandler
Provide a class implementing ErrorHandler and register it, so every uncaught error flows through your handleError. Add context such as the route or user id, and send the error to monitoring. Keep the handler free of logic that can itself throw, or you risk an error loop.
Step 2: Decide what the user sees
A generic error is sent to monitoring, but users should see a short, safe message, not a stack trace or internal detail. Show a toast or a fallback view and offer a retry, so the failure is recoverable where possible. Logging and user messaging are separate concerns.
Step 3: Handle expected errors locally first
Wrap HTTP calls so a 404 or a validation failure is handled by the caller and never reaches the global handler. Reserve the global handler for genuinely unexpected errors: a null dereference, a failed invariant or a rendering bug. This keeps the global handler meaningful.
Worked scenario
The provider replaces the default handler with one that reports and logs.
import { ErrorHandler, Injectable } from '@angular/core';
@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
handleError(error: unknown): void {
const message = error instanceof Error ? error.message : String(error);
console.error('Uncaught error:', message);
// report to monitoring here
}
}Walk through the example
Angular calls handleError for errors that no try/catch or catchError handled, so this is the single place for reporting. The handler runs for programming errors, not for a rejected HTTP response you already mapped. Registering it in the app providers replaces the console-only default.
Common mistake
Swallowing the error by doing nothing in handleError, which hides bugs from monitoring, or showing error.message directly to users, which can leak internals. Another is letting expected HTTP errors reach the global handler, which floods monitoring with noise and hides real defects.
Verify the behavior
Throw an error in a component and confirm handleError receives it and the app shows the fallback. Trigger a handled HTTP error and confirm it does not reach the global handler. Assert the monitoring call includes enough context to reproduce the failure.
Interview exercise
Where should a failed HTTP request be handled: locally or in the global handler?
Answer and reasoning
Locally, with catchError in the service or component that issued it, because the caller knows whether to retry, show an inline message or fall back. Only if no layer handles it should it reach the global handler, which is for unexpected errors. Keeping expected failures local makes the global handler a real signal rather than a catch-all.
Continue learning
Compare error boundaries in Angular HTTP error handling and retry and HTTP interceptors. Read the Angular error handling guide and try the Angular interview questions.