Implementing a Global Error Handler in Angular
Angular applications can encounter errors during runtime, such as network request failures, type errors, or unhandled exceptions. A global error handler provides a centralized mechanism to catch these errors, log them appropriately, and potentially display user-friendly messages, preventing abrupt application crashes and improving the user experience. This challenge asks you to implement such a handler.
Problem Description
You need to create a global error handler service in Angular that intercepts and handles all unhandled exceptions thrown within your application. This service should:
- Catch Unhandled Exceptions: The handler must subscribe to the
ErrorHandlerservice provided by Angular and catch any errors that are not already handled elsewhere. - Log Errors: Log the error details (message, stack trace) to the console and, ideally, to a remote logging service (e.g., Sentry, Firebase Analytics - for this challenge, console logging is sufficient).
- Provide User Feedback (Optional): Display a user-friendly error message to the user, avoiding technical details that might be confusing. This can be a simple alert or a more sophisticated error page. For this challenge, displaying a simple alert is sufficient.
- Prevent Application Crash: Ensure that the application does not crash due to unhandled exceptions.
Key Requirements:
- The error handler should be a singleton service.
- The error handler should be registered with the Angular
ErrorHandlerservice. - The error handler should gracefully handle errors without disrupting the application's functionality.
Expected Behavior:
When an unhandled exception occurs within the Angular application, the global error handler should:
- Intercept the exception.
- Log the error details to the console.
- Display a user-friendly alert message (e.g., "An unexpected error occurred. Please try again later.").
- Continue application execution.
Edge Cases to Consider:
- Errors occurring during initialization.
- Errors occurring within asynchronous operations (e.g., promises, observables).
- Errors occurring in third-party libraries.
- Handling errors in a production environment vs. a development environment (e.g., sending errors to a remote logging service in production). For this challenge, focus on the core functionality.
Examples
Example 1:
Input: An unhandled exception is thrown: `throw new Error('Something went wrong!');`
Output:
- Console log: `Error: Something went wrong!`
`at ...` (stack trace)
- User alert: "An unexpected error occurred. Please try again later."
Explanation: The global error handler catches the exception, logs it to the console, and displays a user-friendly alert.
Example 2:
Input: An asynchronous operation fails: `myObservable.subscribe({ error: (err) => { throw err; } });`
Output:
- Console log: `Error: [Error message from observable]`
`at ...` (stack trace)
- User alert: "An unexpected error occurred. Please try again later."
Explanation: The error thrown from the observable is caught by the global error handler, logged, and an alert is displayed.
Constraints
- The solution must be written in TypeScript.
- The solution must be compatible with Angular versions 9 and above.
- The error handler should not introduce any performance bottlenecks. Console logging should be efficient.
- The user alert should be simple and non-intrusive.
Notes
- Consider using Angular's dependency injection to register the error handler.
- The
ErrorHandlerservice provides a mechanism for handling errors globally. - You can use a simple
alert()function for displaying user feedback, but more sophisticated error handling might involve displaying a custom error component. - Focus on the core functionality of catching and logging unhandled exceptions. Remote logging and advanced error reporting are beyond the scope of this challenge.