Angular Error Handling — Made Easy.
(Like, super easy)
In this article I will walk you through how to automate all of your Angular application’s errors taking a centralised, global approach, catching all of your applications errors and displaying the messages in a consistent and delightful way to your users. There is a bit of a set up involved, but if you get this done at the beginning of your project, you will not have to worry about it again.
Let’s jump right in.
Error Handler Class
Angular provides a hook for centralised exception handling, called ErrorHandler
, as default it prints an error message to the console. We can intercept the error handling and write a custom exception handler that replaces this default behaviour.
I’ve created a new typescript file in the app directory and called it global-error-handler.ts
. In this class, I created a new injectable which implements Angular’s Error Handler and the method handleError. When any error is thrown, client or server, it will get caught by this method where we can then handle how we wish.
To ensure this works, register your new GlobalErrorHandler
in the app.module.ts
in with your providers, like the following:
Build a Notification Service
Before we add any more code to our GlobalErrorHandler
class, let’s add a service to our app that we can call to display the error messages to our users.
Let’s quickly break the code down.
As you can see, I am displaying the two error types differently. Client side errors by an Angular Material’s snack bar, then server side errors by a pop up window, here I used an Angular Material Dialog. This is a personal preference and you can display your error message to appropriately fit your app.
I’ve also added a third function, showNonErrorSnackBar()
to display any messages to the users that are not errors, such as, lost internet connection or user feedback for successful actions.
Http Interceptor
If you are unaware what HttpInterceptor
is, it does exactly what it says on the tin, it intercepts and handles an HttpRequest
or HttpResponse
. There are many ways to use an interceptor and in the resource section of this article I’ll leave some links to some great post. For or this example, we’re simply going to intercept server errors.
We’re using the RxJS retry operator to resubscribe to the observable one more time in case the user gets a timeout, with this, it will retry once before throwing the error.
The condition checks the error’s status for a 401 unauthorised error
, inside this condition you would refresh the token if your app has a token based security, if not respond accordingly.
Register the ServerErrorInterceptor
in the app.module.ts
with the other providers and theGlobalErrorHandler
class.
Bring Everything Together
Now let’s finish off the GlobalErrorHandler
and complete the set up.
In the handlerError
we are checking if the error is either a server error or client error and responding accordingly, while also logging every exception to the console.
Conclusion
That’s it. With this solution, we have centralised our application’s error handling by overriding the default behaviour of Angular’s ErrorHandler
and organised the error types, hopefully giving our users a better experience.
From here you can start to build upon it, maybe add a service that logs all the errors to a server or a service that notifies your team’s slack or team channel when an error has occurred.
Decent, thoughtful error handling is the cornerstone for any application and with this solution you should have a solid foundation.