Angular Interview Questions

34 Questions
Angular

Angular

FrontendWeb Development

Question 27

How do you handle errors in Angular applications?

Answer:

Handling errors in Angular applications is crucial for providing a robust and user-friendly experience. Angular provides several mechanisms and best practices for error handling, including global error handling, HTTP error handling, and using specific Angular features like interceptors and guards. Here’s an overview of various strategies to handle errors in Angular applications:

1. Global Error Handling:

Global error handling allows you to catch and handle errors that are not specifically caught in other parts of your application.

Implementation:

  1. Create an Error Handler Service:

    • Implement the ErrorHandler interface to create a global error handler.
    • Example:
      import { ErrorHandler, Injectable } from '@angular/core';
      
      @Injectable()
      export class GlobalErrorHandler implements ErrorHandler {
        handleError(error: any): void {
          // Custom error handling logic
          console.error('An error occurred:', error);
        }
      }
  2. Register the Global Error Handler:

    • Provide the custom error handler in your AppModule.
    • Example:
      import { NgModule, ErrorHandler } from '@angular/core';
      import { BrowserModule } from '@angular/platform-browser';
      import { AppComponent } from './app.component';
      import { GlobalErrorHandler } from './global-error-handler.service';
      
      @NgModule({
        declarations: [AppComponent],
        imports: [BrowserModule],
        providers: [{ provide: ErrorHandler, useClass: GlobalErrorHandler }],
        bootstrap: [AppComponent]
      })
      export class AppModule {}

2. HTTP Error Handling:

Handling errors from HTTP requests is a common requirement in Angular applications. The HttpClient module provides ways to catch and handle errors from HTTP requests.

Implementation:

  1. Using HttpClient with Error Handling:
    • Use the catchError operator from RxJS to handle HTTP errors.
    • Example:
      import { Injectable } from '@angular/core';
      import { HttpClient, HttpErrorResponse } from '@angular/common/http';
      import { throwError } from 'rxjs';
      import { catchError } from 'rxjs/operators';
      
      @Injectable({
        providedIn: 'root'
      })
      export class DataService {
        private apiUrl = 'https://api.example.com/data';
      
        constructor(private http: HttpClient) {}
      
        getData() {
          return this.http.get(this.apiUrl).pipe(
            catchError(this.handleError)
          );
        }
      
        private handleError(error: HttpErrorResponse) {
          let errorMessage = 'Unknown error!';
          if (error.error instanceof ErrorEvent) {
            // Client-side error
            errorMessage = `Error: ${error.error.message}`;
          } else {
            // Server-side error
            errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
          }
          return throwError(errorMessage);
        }
      }

3. Error Handling with Interceptors:

HTTP interceptors are a powerful way to handle errors for all HTTP requests in a centralized manner.

Implementation:

  1. Create an HTTP Interceptor:

    • Implement the HttpInterceptor interface to intercept HTTP requests and responses.
    • Example:
      import { Injectable } from '@angular/core';
      import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http';
      import { Observable, throwError } from 'rxjs';
      import { catchError } from 'rxjs/operators';
      
      @Injectable()
      export class HttpErrorInterceptor implements HttpInterceptor {
        intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
          return next.handle(request).pipe(
            catchError((error: HttpErrorResponse) => {
              let errorMessage = 'Unknown error!';
              if (error.error instanceof ErrorEvent) {
                errorMessage = `Error: ${error.error.message}`;
              } else {
                errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
              }
              // Show the error to the user
              console.error(errorMessage);
              return throwError(errorMessage);
            })
          );
        }
      }
  2. Register the Interceptor:

    • Provide the interceptor in your AppModule.
    • Example:
      import { NgModule } from '@angular/core';
      import { BrowserModule } from '@angular/platform-browser';
      import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
      import { AppComponent } from './app.component';
      import { HttpErrorInterceptor } from './http-error.interceptor';
      
      @NgModule({
        declarations: [AppComponent],
        imports: [BrowserModule, HttpClientModule],
        providers: [
          { provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptor, multi: true }
        ],
        bootstrap: [AppComponent]
      })
      export class AppModule {}

4. Error Handling in Guards:

Angular route guards can be used to handle errors related to navigation.

Implementation:

  1. Create an Error Handling Guard:

    • Implement the CanActivate interface to handle errors during route activation.
    • Example:
      import { Injectable } from '@angular/core';
      import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
      
      @Injectable({
        providedIn: 'root'
      })
      export class AuthGuard implements CanActivate {
        constructor(private router: Router) {}
      
        canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
          const isAuthenticated = false; // Replace with actual authentication check
          if (!isAuthenticated) {
            // Redirect or show an error message
            this.router.navigate(['/login']);
            return false;
          }
          return true;
        }
      }
  2. Register the Guard:

    • Use the guard in your route definitions.
    • Example:
      const routes: Routes = [
        {
          path: 'protected',
          component: ProtectedComponent,
          canActivate: [AuthGuard]
        }
      ];
      
      @NgModule({
        imports: [RouterModule.forRoot(routes)],
        exports: [RouterModule]
      })
      export class AppRoutingModule {}

5. Component-Level Error Handling:

You can also handle errors at the component level, especially for handling specific scenarios.

Implementation:

  1. Using Try-Catch Blocks:
    • Use try-catch blocks within component methods to handle synchronous errors.
    • Example:
      @Component({
        selector: 'app-example',
        templateUrl: './example.component.html'
      })
      export class ExampleComponent {
        fetchData() {
          try {
            // Synchronous code that may throw an error
          } catch (error) {
            console.error('Error:', error);
          }
        }
      }

In Summary:

Handling errors in Angular applications involves using global error handlers, HTTP error handling with services and interceptors, route guards for navigation-related errors, and component-level error handling. These strategies ensure that errors are managed gracefully, providing better user experiences and easier debugging. Implementing these techniques helps maintain robust, resilient, and user-friendly Angular applications.

Recent job openings