It’s crucial to handle failures while creating Angular Error Handling applications appropriately. More than ever, there is a need for a robust client-side error handling solution in the era of cutting-edge front-end websites. Error handlers offer a chance to give the user helpful information and gather vital information for improvement.
In this blog post, we’re going to look at error handling in Angular as part of a practical example. We’ll explore how errors are caught and held in an application built with Angular, how they might be displayed to the user, and any actions required when processing errors.
In this guide, you will learn how to use the Angular CLI to generate a new Angular project. check out the links below.
What is error handling?
Error handling is a big deal. It’s the first step of looking into something that could go wrong and either helping or not helping it. It can sometimes be confusing on Angular how error handling works and what should happen when an error occurs.
There are two types of error handling mechanisms in Angular.
- Server-side error
- Client-side error
How to handle Server side errors?
We can catch the HTTP Errors at three different places on the client side. Following are a few ways to manage Angular error handling to improve customer experience.
- Service : HttpClient
- Globally: HttpInterceptor
- Component: observable
How to handle Client side errors?
Angular client-side error handling can be done in one of two ways; by throwing a mistake or catching and re-throwing the error
- Global Error handler: ErrorHandler
- Component: try-catch
Server-side errors
Server-side errors are errors that occur on the server. They can be caused by something on the server side going wrong, incorrect data, logical error, and a misconfigured application.
Server Side Errors Handling with HttpClient
HttpClient is helpful in Angular error handling because of its inbuilt feature. HttpClient will eliminate network challenges and front-end side errors from the client using the ErrorEvent module. Furthermore, the program also uses the Server-side to resolve user errors, and back-end coding errors.
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http'
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs/internal/observable/throwError';
@Injectable({
providedIn: 'root'
})
export class HttpService {
constructor(private httpClient: HttpClient) { }
// :: example 1
getUsers() {
this.httpClient
.get("data-url").pipe(
catchError((error: HttpErrorResponse) => {
// error logging, you can do a lot more, see below
console.error('An error occurred:', error.error)
return throwError(error)
})
)
}
// :: example 2
getBooks() {
this.httpClient
.get("data-url")
.subscribe(
data => { // success response
console.log('success', data)
},
error => { // error response
console.log('oops', error)
}
);
}
}
And here is an example of a service that calls the API above using an HTTP GET, and displays the data on the screen. Let’s break down this example.
- We are using the HttpClient service of the HttpClientModule, and injecting it into the constructor.
- To catch the error in the observable stream, we are using catcherror operator.
Server Side Errors Handling with HttpInterceptor
Another helpful Angular error handling program is called HttpInterceptor. The Interceptor catches HTTP requests and other responses before passing them on to the next stage. Its assistive qualities cannot be ignored. The tool offers the possibility to alter headers, add tokens, and modify other requirements to eliminate Angular problems.
import { Injectable } from '@angular/core';
import {
HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { MatSnackBar } from '@angular/material/snack-bar';
@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
constructor(private _snackBar: MatSnackBar) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.pipe(
catchError((err: HttpErrorResponse) => {
this.handleServerSideError(err);
return throwError(err);
})
);
}
private handleServerSideError(error: HttpErrorResponse) {
switch (error.status) {
case 400: // means the request could not be understood by the server.
this._snackBar.open("Bad Request, please try again later .");
break;
case 401: // means lacks valid authentication credentials for the target resource.
this._snackBar.open("Unauthorized, please try again later.");
break;
case 403: // means you are not allowed access to the target resource.
this._snackBar.open("Forbidden access is denied");
break;
case 500: // means there's an issue or temporary glitch with the application's programming
this._snackBar.open("Internal server error, please try again later.");
break;
}
}
}
HttpInterceptor uses its writing to discover the root module. As a result, everything takes place without leaving the application, even when the loading is delayed. The user application is easy to maintain, thanks to the HttpInterceptor. It eliminates errors automatically without manual involvement. You can use it to modify error pathways to attain all access to the application.
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HttpErrorInterceptor } from './interceptor/http.interceptor';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule
],
providers: [
{
provide:HTTP_INTERCEPTORS,
useClass:HttpErrorInterceptor,
multi:true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
HttpInterceptor maintains an error log for record-keeping services. The record is available on the server. However, we can use Rollbar to do the job instead of manually entering the log to access information.
Server Side Error handling in Component
Angular error handling in Component, In order to handle errors on component, we need to make use of the HttpClientModule to make HTTP Get request and inject HttpClient service in the constructor. We subscribe to the HttpClient’s get() method in our component class. in error block, we can handle errors.
import { Component } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
constructor(private _http: HttpClient) {
}
ngOnInit() {
this._http
.get("data-url")
.subscribe(
(res: any) => {
console.log("data", res);
},
(error: HttpErrorResponse) => {
console.log("error", error.message);
})
}
}
Client-side errors
Client-side errors are errors that occur on the client or browser side. They can be caused by the client-side code not functioning as it should, or the browser or application making a mistake. The error will either be displayed in the browser console or will cause the browser to stop executing the code. There are two types of client-side errors: syntax errors and runtime errors. Syntax errors occur when the code is not valid in javascript.
Client Side Global Error handling with ErrorHandler
The other way of Angular error handling is the ErrorHandler (a built-in feature of Angular ), which is a more flexible solution that allows you to track all of your errors in one place. This will enable you to track precisely what went wrong without making assumptions about how your user will react to an error message.
import { ErrorHandler, Injectable } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
constructor(private _snackBar: MatSnackBar) {
}
handleError(error: TypeError) {
// your custom error handling logic
console.log("error", error);
this.displayError(error);
}
private displayError(error: TypeError): void {
// call error logging API or display error
this._snackBar.open(error.message);
}
}
Angular error handling using ErrorHandler
import { ErrorHandler, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { GlobalErrorHandler } from './GlobalErrorHandler ';
import { MatSnackBarModule } from '@angular/material/snack-bar';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
MatSnackBarModule
],
providers: [
{ provide: ErrorHandler, useClass: GlobalErrorHandler }
],
bootstrap: [AppComponent]
})
export class AppModule { }
The Example of Angular error handling in component
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
element: any[] = [];
ngOnInit() {
const element = this.element[1].p;
}
}
Angular Error handling with Try Catch
One is the catch method, called as soon as an error occurs, and allows you to catch and deal with it. This can be helpful to you if you want to log the error, skip some content or display some information in the browser’s console.
import { Component } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
element: any[] = [];
constructor(private _snackBar: MatSnackBar) {
}
ngOnInit() {
try {
const element = this.element[1].p;
}
catch (error: any) {
this._snackBar.open(error.message);
}
}
}
Best practices for Error handling in Angular
We can catch the HTTP Errors at three different places. Following are a few best practices for Angular error handling to manage Angular error handling to improve customer experience.