Error Handling In Angular

Error Handling In Angular

In this article, we learn angular error handling. Additionally, we discover how to use Angular to build custom or global error handlers. We discover some of the finest practices and the reasons why we must handle errors. We will learn a few techniques in the conclusion, including how to show user notification pages and inject services into global error handlers.

Why Handle Errors?

Error handling is crucial to the design of the application. When something goes wrong, JavaScript has the ability to throw errors. For instance, the following circumstances cause the Javascript to throw problems.

  1. when a variable that is not present is referenced.
  2. The value entered does not fall inside the permitted range.
  3. Understanding syntactically flawed code
  4. When a value is not what was anticipated
  5. JavaScript engine internal issues

Aside from the aforementioned, unanticipated problems can occur at any time. as well as HTTP issues like an unauthorized user, session expired, no internet, broken connection, null pointer exception, and so forth.

While handling failures, Angular does nothing more than write them to the console. And neither the user nor the developer will find that valuable.

In Angular, there are two different sorts of error handling mechanisms. The first one detects all client-side errors, whereas the second one detects HTTP errors.

HTTP Errors

When you send an HTTP request using the HttpClient Module, HTTP errors are generated. Once more, there are two types of errors. Unauthorized user, session expiration, server offline, and other ones are generated by the server. While attempting to create an HTTP request, the other one is generated at the client's end. These problems may involve the network or the request generation process, for example.

The HTTP Interceptors deal with HTTP failures.

Client Side Errors

This category includes all other mistakes that the code may have produced. The ErrorHandler class, which is Angular's default error handler, is responsible for handling these.

Default Error Handling in Angular

The @angular/core module's Errorhandler class, which handles default Error handling in Angular, is responsible for this. This class of global error handlers catches any exceptions that arise within the App. This class has a handleError function (error). Anytime an unhandled exception is thrown by the application anywhere in the code, angular catches it. The method handleError(error) is then called, writing the error messages to the browser console.

Example

a new Angular application should be made. To app.component.html and app.component.ts, add the following line of code.

Add the following code under the app.component.html file.

<h1> {{title}} </h1>
 
<button (click)="throwError1()"> Throw Error-1 </button>
<button (click)="throwError2()"> Throw Error-2 </button>
 
<router-outlet></router-outlet>

Now, open the app.component.ts file and put the following code.
import { Component } from '@angular/core';
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent
{
    title: string = 'Global Error Handler in Angular' ;
 
    throwError1() {
      var a= b;  
    }
 
    throwError2() {
      try {
        var a= b;  
      } catch (error) {
         //here you can handle the error
         //
      }
    }
}

The statement var a= b;, where b is not declared, is used in the code to simulate an error. The second method, throwError2(), uses a try..catch block to handle the error while the first method, throwError1(), does not.

Open the Chrome Developer Tool while running the application. Select "throw error" from the menu. As seen in the accompanying image, Angular's default error handler intercepts the error and writes it to the console.

But because the try..catch block is used to manage it, pressing the throw error 2 button does not activate the error handler.

Throw error must be used if the error is not being handled in the try..catch block so that the default error handler can handle it.

Default Error Handling In Angular

Global Error Handler

While developing the software, a decent choice is provided by the built-in ErrorHandler, which is a straightforward solution. Finding the problem that was thrown in the production environment is not helped, though. The errors that occur on the end of the user are unknown to us.

Consequently, it is recommended that we develop our own global error handler class because
  • We can provide the user with a straightforward error page and the option to try the operation again.
  • The back-end server, where we can read all the errors, is where we can log the errors. Then, we can modify the application as needed to fix the problem.

How to Create Global Error Handler?

The steps listed below must be used in order to construct a custom error handler service.

creating a GlobalErrorHandlerService that implements the ErrorHandler is the first step.
After that, take care of the error by overriding the handleError(error) method.
export class GlobalErrorHandlerService implements ErrorHandler {
 
  constructor() { 
  }
 
  handleError(error) {
     console.error('An error occurred:', error.message);
  }
  
}

Next, use the token ErrorHandler to register the GlobalErrorHandlerService in the Application root module.
@NgModule({
  ------
  providers: [
    { provide: ErrorHandler, useClass: GlobalErrorHandlerService },
  ]
})
export class AppModule { } 

Error Handler Example

Add the following code to global-error-handler.service.ts after creating it.
import { ErrorHandler, Injectable} from '@angular/core';
 
@Injectable()
export class GlobalErrorHandlerService implements ErrorHandler {
 
    constructor() { 
    }
  
    handleError(error) {
       console.error('An error occurred:', error.message);
       console.error(error);
       alert(error);
   }
 
}

The GlobalErrorHandlerService should then be registered using the injection token ErrorHandler by opening the pp.module.ts file.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule,ErrorHandler } from '@angular/core';
 
import { AppComponent } from './app.component';
import  {GlobalErrorHandlerService} from './global-error-handler.service';
 
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
  ],
  providers: [
    { provide: ErrorHandler, useClass: GlobalErrorHandlerService },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

When you run the app, you'll see that clicking the throw error button causes our custom error handler to be called.

Global Error Handling In Angular

Best Practices in Handling Errors

Now that we know how to handle problems, here are some considerations for creating an error handler service.

  • To handle the known mistakes, use a try.. catch block. Treat it appropriately. Re-throw it if you are unable to catch it.
  • To catch all unhandled failures and notify the user, use a global error handler.
  • HTTP Interceptors must be used in place of the ErrorHandler in order to handle HTTP errors. For information on how to handle HTTP errors with Angular, see this article.
  • In the error handler, determine the type of issue and take appropriate action.
    • For instance, if there is a back-end error (HTTP Error), you can use the HTTP Status Code to take the appropriate action.
    • 401 You can direct the user to the login page if there is an unauthorized error.
    • 500 Error Internal to Server You can notify the server administrator and request the user to try again after some time.
  • Log any further problems to the back end server if necessary ( or to any third party error providers). After that, you can review the logs and modify the app as needed.

Advice for the Error Handler

Adding additional features to the global error handler


The error handler service is created by Angular before the providers. If not, it won't have the ability to detect mistakes that happen extremely early in the application. Additionally, the ErrorHandler won't have access to the angular providers.

What would happen if we wanted to use a different service in the error handler. Then, in order to directly inject the dependency without depending on the dependency injection framework, we must use the Injector instance.

To begin with, we must import the injector.

The GlobalErrorHandlerService injector must then be added.

Finally, use the injector to obtain any necessary service instances.

The injector is used by the following example service to obtain the router service.
import { ErrorHandler, Injectable, Injector} from '@angular/core';
import { Router } from '@angular/router';
 
@Injectable()
export class GlobalErrorHandlerService implements ErrorHandler {
 
    constructor(private injector: Injector) {
    }
 
    handleError(error) {
 
        let router = this.injector.get(Router);
        console.log('URL: ' + router.url);
        console.error('An error occurred:', error.message);
       
       alert(error);
   }
}

User Notification Page

Using the error page to inform the user of the mistake is good design practise.

Add the following code under the error.component.ts file
import { Component } from '@angular/core';
 
@Component({
  template: `
     <h2>An unknown error occurred.</h2>
  `
})
export class ErrorComponent {
} 

Remember to include it in the routing module.

Add the following code under the app-routing.module.ts file
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ErrorComponent } from './error.component ';
 
const routes: Routes = [
  {path: 'error', component: ErrorComponent }
]
 
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: []
})
export class AppRoutingModule { }

Additionally, inject the router and use a router in the GlobalErrorHandlerService. To access the customised error page, use navigate(['/error']).
import { ErrorHandler, Injectable, Injector} from '@angular/core';
import { Router } from '@angular/router';
 
@Injectable()
export class GlobalErrorHandlerService implements ErrorHandler {
 
    constructor(private injector: Injector) {    }
 
    handleError(error) {
 
        let router = this.injector.get(Router);
        console.log('URL: ' + router.url);
        console.error(error);
       
        router.navigate(['/error']);
   }
 
}

Conclusion

In this article, we learn about the error handling in angular. In the next article, we learn about HTTP Error Handling in Angular.

Post a Comment

Previous Post Next Post