Learn the basics of Angular error handler.
Tags: angular, webdev
Published: 2020-04-04 17:11:32

In this article, we'll discuss three basic principles of handling the error of an Angular app.

# 1. Handle bootstrap level error
This type of error is the most dangerous because they can block our entire app. There are a few reasons this error can happen for example, if we made any mistake in the component constructor or module constructor or if the root route is failed to load or render. Now the question is how we can track those errors? The answer is simple, if we bootstrap our app using ´CLI´ then it is already added in our ´main.ts´ file

```typescript
platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch(err => console.error('Handle bootstrap level error', err));
```
Otherwise, we need to add the `catch` block ourselvs.

# 2. Handle module-level error
The module-level error means regular errors. While we are interacting with the app, some exceptions can happen. Angular provides a very clear guideline of how we can handle this type of errors. This is a very good practice to set up a generic handler that can handle all types of errors. Angular has a generic error handler class called `ErrorHandler`. We need to inherit this class. This class has a generic method called `handleError` that we need to override. Let's implement this

```typescript
export class GenericErrorHandler implements ErrorHandler {
    handleError(error: any): void {
        console.error(error);
    }
}
```
Now we need to add this handler to our module 
```typescript
@NgModule({
//..
providers: [
    { provide: ErrorHandler, useClass: GenericErrorHandler }
  ],
})
```
One of the key tasks of this generic error handler is tracking the error. We may want to post the errors to the error tracker. The error tracker implementation should be here.

 *I would prefer to have a single error handler for the entire app* To ensure this we need to add this handler to the `AppModule`. There can be an exception like if we made an app that has client-side/customer-facing and admin-side both in a single app. We may want to handle errors separately. In that case, we can add two different error handlers on the top-level module like `AppClientModule`, `AppAdminModule`.

# 3. Handle in component level
Definitely we can handle errors in component level. So there is a question what do we mean by handling errors in the component level? If we add `try-catch` or `promise-catch` inside the component then it is handled at the component level. In that case, our generic or global error handler can not detect this error. 

So it a downside of handling errors in component level. But there are cases when actually we need to do this. For example, we want to show a very specific message to the user if something is broken or if the user didn't fill the form correctly. 

We need to handle this case in a way so that our generic error handler can perform its task. As we already know, one of the key tasks of the generic error handler is tracking errors. 

I found two ways to perform this task

1. Re-throw the error with the original message, like
    ```typescript
    try {
      let foo: any;
      console.log(foo.bar);
    } catch (error) {
      console.error('Handle error in component level: ', error);
      throw new Error(error);
    }
    ```
2. Add a shared service at the application level. Application-level services are top-level, they can be accessed from all over the application. From the generic error handler class and inside the component we can use this service to track the error.

# Conclusion
I hope you understand the different levels of errors and how to handle it gracefully. If you have any question please use the comment box below :)