Angular httpclient обработка ошибок

You have some options, depending on your needs. If you want to handle errors on a per-request basis, add a catch to your request. If you want to add a global solution, use HttpInterceptor.

Open here the working demo plunker for the solutions below.

tl;dr

In the simplest case, you’ll just need to add a .catch() or a .subscribe(), like:

import 'rxjs/add/operator/catch'; // don't forget this, or you'll get a runtime error
this.httpClient
      .get("data-url")
      .catch((err: HttpErrorResponse) => {
        // simple logging, but you can do a lot more, see below
        console.error('An error occurred:', err.error);
      });

// or
this.httpClient
      .get("data-url")
      .subscribe(
        data => console.log('success', data),
        error => console.log('oops', error)
      );

But there are more details to this, see below.

Method (local) solution: log error and return fallback response

If you need to handle errors in only one place, you can use catch and return a default value (or empty response) instead of failing completely. You also don’t need the .map just to cast, you can use a generic function. Source: Angular.io — Getting Error Details.

So, a generic .get() method, would be like:

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from "@angular/common/http";
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/empty';
import 'rxjs/add/operator/retry'; // don't forget the imports

@Injectable()
export class DataService {
    baseUrl = 'http://localhost';
    constructor(private httpClient: HttpClient) { }

    // notice the <T>, making the method generic
    get<T>(url, params): Observable<T> {
      return this.httpClient
          .get<T>(this.baseUrl + url, {params})
          .retry(3) // optionally add the retry
          .catch((err: HttpErrorResponse) => {

            if (err.error instanceof Error) {
              // A client-side or network error occurred. Handle it accordingly.
              console.error('An error occurred:', err.error.message);
            } else {
              // The backend returned an unsuccessful response code.
              // The response body may contain clues as to what went wrong,
              console.error(`Backend returned code ${err.status}, body was: ${err.error}`);
            }

            // ...optionally return a default fallback value so app can continue (pick one)
            // which could be a default value
            // return Observable.of<any>({my: "default value..."});
            // or simply an empty observable
            return Observable.empty<T>();
          });
     }
}

Handling the error will allow you app to continue even when the service at the URL is in bad condition.

This per-request solution is good mostly when you want to return a specific default response to each method. But if you only care about error displaying (or have a global default response), the better solution is to use an interceptor, as described below.

Run the working demo plunker here.

Advanced usage: Intercepting all requests or responses

Once again, Angular.io guide shows:

A major feature of @angular/common/http is interception, the ability to declare interceptors which sit in between your application and the backend. When your application makes a request, interceptors transform it before sending it to the server, and the interceptors can transform the response on its way back before your application sees it. This is useful for everything from authentication to logging.

Which, of course, can be used to handle errors in a very simple way (demo plunker here):

import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse,
         HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/empty';
import 'rxjs/add/operator/retry'; // don't forget the imports

@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request)
      .catch((err: HttpErrorResponse) => {

        if (err.error instanceof Error) {
          // A client-side or network error occurred. Handle it accordingly.
          console.error('An error occurred:', err.error.message);
        } else {
          // The backend returned an unsuccessful response code.
          // The response body may contain clues as to what went wrong,
          console.error(`Backend returned code ${err.status}, body was: ${err.error}`);
        }

        // ...optionally return a default fallback value so app can continue (pick one)
        // which could be a default value (which has to be a HttpResponse here)
        // return Observable.of(new HttpResponse({body: [{name: "Default value..."}]}));
        // or simply an empty observable
        return Observable.empty<HttpEvent<any>>();
      });
  }
}

Providing your interceptor: Simply declaring the HttpErrorInterceptor above doesn’t cause your app to use it. You need to wire it up in your app module by providing it as an interceptor, as follows:

import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpErrorInterceptor } from './path/http-error.interceptor';

@NgModule({
  ...
  providers: [{
    provide: HTTP_INTERCEPTORS,
    useClass: HttpErrorInterceptor,
    multi: true,
  }],
  ...
})
export class AppModule {}

Note: If you have both an error interceptor and some local error handling, naturally, it is likely that no local error handling will ever be triggered, since the error will always be handled by the interceptor before it reaches the local error handling.

Run the working demo plunker here.

Обработка ошибок¶

При работе с сетью и http нередко могут происходить ошибки, например, в момент запроса сеть стала недоступна, неправильно указан адрес и соответственно не найден ресурс, либо доступ к ресурсу ограничен, либо другие ошибки. Перехват ошибок позволит выяснить проблему и каким-то образом обработать их, например, вывести пользователю сообщение об ошибке.

Например, изменим код компонента AppComponent:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import { Component, OnInit } from '@angular/core'
import { HttpService } from './http.service'
import { User } from './user'

@Component({
  selector: 'my-app',
  template: `
    <div>{{ error }}</div>
    <ul>
      <li *ngFor="let user of users">
        <p>Имя пользователя: {{ user?.name }}</p>
        <p>Возраст пользователя: {{ user?.age }}</p>
      </li>
    </ul>
  `,
  providers: [HttpService],
})
export class AppComponent implements OnInit {
  users: User[] = []
  error: any
  constructor(private httpService: HttpService) {}

  ngOnInit() {
    this.httpService.getUsers().subscribe(
      (data) => (this.users = data),
      (error) => {
        this.error = error.message
        console.log(error)
      }
    )
  }
}

Метод subscribe() в качестве второго параметра принимает обработчик, который вызывается в случае возникновения ошибки. В этом обработчике мы можем получить ошибку и обработать ее. Ошибка собственно представляет объект, из которого мы можем получить ряд данных. В частности, свойство message позволяет получить сообщение об ошибке, а свойство statusCode — статусный код ответа. И в данном случае в компоненте определена переменная для хранения сообщения об ошибке. И в шаблоне эта переменная выводится на веб-страницу. И например, при обащении к несуществующему файлу json мы получим следующую ошибку:

Скриншот приложения

Кроме того, для перехвата ошибок к объекту Observable, который является результатом запроса, можно использовать функцию catchError(). Так, возьмем код сервиса из прошлой темы и добавим к нему обработку ошибок:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { Injectable } from '@angular/core'
import { HttpClient } from '@angular/common/http'
import { User } from './user'
import { Observable, throwError } from 'rxjs'
import { map, catchError } from 'rxjs/operators'

@Injectable()
export class HttpService {
  constructor(private http: HttpClient) {}

  getUsers(): Observable<User[]> {
    return this.http.get('usersP.json').pipe(
      map((data) => {
        let usersList = data['usersList']
        return usersList.map(function (user: any) {
          return { name: user.userName, age: user.userAge }
        })
      }),
      catchError((err) => {
        console.log(err)
        return throwError(err)
      })
    )
  }
}

Для имитации исключения здесь передается заведомо несуществующий адрес usersP.json. Для обработки ошибок в метод pipe() передается в качестве второго параметра функция для обработки ошибок. В качестве подобной функции используется функция catchError(). Она принимает объект ошибки, который затем выводится на консоль. С помощью вывода на консоль мы можем исследовать объект. Это тот же объект, который мы выше получаем в AppComponent в методе subscribe. С помощью метода throwError() возвращается результат — новый объект Observable, который содержит информацию об ошибке.

Home  »  Angular   »   Error Handling in Angular 16 Tutorial with Examples

Learn Error handling in Angular 16, we will take the best approach with RxJS catchError operator and HttpInterceptor to handle client-side errors gracefully.

A proper Error handling makes an application most helpful for users from the user experience aspect, error handlers report a user correctly what causing the problem.

It also notifies developers in the development phase about the error reason, which assists them to fix it before it goes live.

These days new technologies are growing faster than ever. This competition is all about making a piece of software better for users be it a final user, product owner or a developer who is building it from scratch. Due to this, user experiences became the trend.

There are two types of errors which might occur in an application, inside errors and outside errors.

Outside Errors: These errors often occur from the server-side and usually starts with (5xxx) status code. These errors return the error message with the proper reason so identifying these errors is easy.

Inside Error: When something unexpected happens, then these errors are thrown. These errors occur with the proper message, which contains the reason for the error occurrence.

Here is the complete List of HTTP status codes.

Next, we practically understand how to handle client-side errors in Angular. A Client-side error handling is one of the features among other various features for developing a user friendly application.

A user gets frustrated when suddenly an app stopped working, and the user doesn’t find the reason for it. It downgrades the overall user experience of the application. To enhance the user experience, we must properly handle errors.

We will use the regular error handling approaches such as handling errors with RxJS operators catchError and throwError and managing errors with HttpClient and HttpInterceptor.

Handle Errors in Angular with HttpClient and RxJS

The simplest way to handle errors in Angular is to use Angular’s HttpClient service along with RxJS operators throwError and catchError. Http request is made, and it returns the data with a response if anything wrong happens then it returns an error object with error status code.

Below is the service in which we used the handleError() function to handle errors in Angular.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';
class Post {
  constructor(public id: string, public title: string, public body: string) {}
}
@Injectable({
  providedIn: 'root',
})
export class PostService {
  private endpoint = 'https://jsonplaceholder.typicode.com/xyz';
  constructor(private http: HttpClient) {}
  getPost(): Observable<Post[]> {
    return this.http
      .get<Post[]>(this.endpoint)
      .pipe(retry(1), catchError(this.handleError));
  }
  handleError(error:any) {
    let errorMessage = '';
    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}`;
    }
    console.log(errorMessage);
    return throwError(() => {
        return errorMessage;
    });
  }
}

Angular Error Handling

In the service, we defined the handleError() method. In this method, we are checking if the error is an instance of ErrorEvent. This function returns either the client-side or server-side error. This error is useful for a single service. Still, when it comes to managing multiple services, then we have to update the handleError function in every service even for a minor change.

Error Handling with HttpClient and HttpInterceptor

To handle errors properly, HttpInterceptor is the best way, and It intercepts Http request. It helps in converting http request before sending and after getting the response from the server. It is better used for updating data format, setting up headers, adding auth tokens, etc. HttpInterceptor service offers a better way to handle errors in an Angular app systematically.

The following ErrorIntercept service can manage multiple services. We are using retry(1) and catchError RxJS operators to check the HttpErrorResponse. This code is centralised in nature and can be managed from one place by far this has been the best way to manage errors in Angular.

Add the following code in error.interceptor.ts:

import {
    HttpEvent,
    HttpHandler,
    HttpRequest,
    HttpErrorResponse,
    HttpInterceptor
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
export class ErrorIntercept implements HttpInterceptor {
    intercept(
        request: HttpRequest<any>,
        next: HttpHandler
    ): Observable<HttpEvent<any>> {
        return next.handle(request)
            .pipe(
                retry(1),
                catchError((error: HttpErrorResponse) => {
                    let errorMessage = '';
                    if (error.error instanceof ErrorEvent) {
                        // client-side error
                        errorMessage = `Error: ${error.error.message}`;
                    } else {
                        // server-side error
                        errorMessage = `Error Status: ${error.status}nMessage: ${error.message}`;
                    }
                    console.log(errorMessage);
                    return throwError(errorMessage);
                })
            )
    }
}

Import HttpClientmodule, HTTP_INTERCEPTORS and ErrorIntercept in app.module.ts, next inject the HTTP_INTERCEPTORS and ErrorIntercept in providers array along with that set multi: true.

import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { ErrorIntercept } from './error.interceptor';
@NgModule({
  declarations: [...],
  imports: [
    HttpClientModule
  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: ErrorIntercept,
      multi: true
    }
  ],
  bootstrap: [...]
})
export class AppModule { }

Here is the post.service.ts:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
class Post {
    constructor(
        public id: string,
        public title: string,
        public body: string
    ) { }
}
@Injectable({
    providedIn: 'root'
})
export class PostService {
    private endpoint = 'https://jsonplaceholder.typicode.com/xyz';
    constructor(private http: HttpClient) { }
    getPost(): Observable<Post[]> {
        return this.http.get<Post[]>(this.endpoint)
    }
}

Conclusion

Finally, we have completed the error handling tutorial with examples. I hope this tutorial helps you to understand the basic concept of handling client-side errors in Angular with RxJS operators and HttpInterceptor.

Recommended Posts:

Обработка ошибок

Последнее обновление: 04.05.2023

При работе с сетью и http нередко могут происходить ошибки, например, в момент запроса сеть стала недоступна, неправильно указан адрес и соответственно не найден
ресурс, либо доступ к ресурсу ограничен, либо другие ошибки. Перехват ошибок позволит выяснить проблему и каким-то образом обработать их, например,
вывести пользователю сообщение об ошибке.

Для перехвата ошибок, которые могут возникнуть при выполнении запроса, можно использовать функцию catchError(). Так,
возьмем код сервиса из прошлой темы и добавим к нему обработку ошибок:

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {User} from './user';
import {Observable, throwError} from 'rxjs';
import { map, catchError} from 'rxjs/operators';
 
@Injectable()
export class HttpService{
    
    errorMessage: String = "";
    constructor(private http: HttpClient){ }
        
    getUsers() : Observable<User[]> {
        return this.http.get('assets/usersP.json').pipe(map((data:any)=>{
            let usersList = data["userList"];
            
            return usersList.map(function(user:any) : User {
                return new User(user.userName, user.userAge);
              });
        }),
        catchError(err => {  
            console.log(err); 
            this.errorMessage = err.message;
            return [];
        }))
    };
}

Прежде всего в сервисе определяется переменная errorMessage, которая будет хранит информацию об ошибке.

Для имитации ошибки в http-клиент передается заведомо несуществующий адрес «usersP.json». Для обработки ошибок в метод
pipe() передается в качестве второго параметра функция для обработки ошибок. В качестве подобной функции здесь применяется функция catchError():

catchError(err => {  
            console.log(err); 
            this.errorMessage = err.message;
            return [];
        })

В качестве параметра функция catchError() принимает функцию, в которую в качестве параметра передается объект ошибки, возникшей
при выполнении запроса. Таким образом, в этой функции мы можем получить ошибку и обработать ее.

Ошибка собственно представляет объект, из которого мы можем получить ряд данных. В частности,
свойство message позволяет получить сообщение об ошибке, а свойство status — статусный код ответа.

Так, в данном случае вся обработка заключается в том, что этот объект выводится на консоль, а свойству errorMessage сервиса
передается сообщение об ошибке (если запрос прошел успешно, то этому свойству присваивается пустая строка).

Стоит отметить, что в функции обработки ошибки нам все равно надо вернуть объект Observable. Для этого мы возвращаем пустой массив:

return [];

Далее будет создан объект Observable>User[]<, который будет содержать пустой массив объектов User.

Например, используем сервис и для этого изменим код компонента AppComponent:

import { Component, OnInit} from '@angular/core';
import { HttpService} from './http.service';
import {User} from './user';
   
@Component({
    selector: 'my-app',
    template: `<div>{{this.httpService.errorMessage}}</div>
                <ul>
                <li *ngFor="let user of users">
                <p>Имя пользователя: {{user?.name}}</p>
                <p>Возраст пользователя: {{user?.age}}</p>
                </li>
            </ul>`,
    providers: [HttpService]
})
export class AppComponent implements OnInit { 
   
    users: User[]=[];
    error:any;
    constructor(public httpService: HttpService){}
      
    ngOnInit(){
          
        this.httpService.getUsers().subscribe({next: data=>this.users=data});
    }
}

С помощью метода subscribe() компонент может получить из сервиса массив объектов User. Если возникнет ошибка, то это будет пустой массив.

Для получения информации об ошибке компонент обращается к свойству errorMessage сервиса и выводит его значение в размеке html.

И например, при обащении к несуществующему файлу json мы получим следующую ошибку:

Передача ошибки в компонент в Angular 16

Это самая примитивная обработка ошибка, которая демонстрирует общий принцип. Естественно в сервисе мы можем определять какое-то другое сообщение об ошибке или как-то иначе обрабатывать ошибку.

In this guide, we learn about Angular HTTP Error Handling. Whenever the error occurs in an HTTP operation, the Angular wraps it in an httpErrorResponse Object before throwing it back. We catch the httpErrorResponse either in our component class or in the data service class or globally. The Global HTTP error handling is done using the Angular HTTP Interceptor.

Suggested Reading: Error Handling in Angular

Table of Contents

  • HttpErrorResponse
  • Catching Errors in HTTP Request
    • Catch Errors in Component
    • Catch Errors in Service
    • Catch error globally using HTTP Interceptor
  • HTTP Error Handling
  • HTTP Error handling example
  • References
  • Summary

HttpErrorResponse

The HttpClient captures the errors and wraps it in the generic HttpErrorResponse, before passing it to our app. The error property of the HttpErrorResponse contains the underlying error object. It also provides additional context about the state of the HTTP layer when the error occurred.

The HTTP errors fall into two categories. The back end server may generate the error and send the error response. Or the client-side code may fail to generate the request and throw the error (ErrorEvent objects).

The server might reject the request for various reasons. Whenever it does it will return the error response with the HTTP Status Codes such as Unauthorized (401), Forbidden (403), Not found (404), internal Server Error (500), etc. The Angular assigns the error response to error property of the HttpErrorResponse.

The client-side code can also generate the error. The error may be due to a network error or an error while executing the HTTP request or an exception thrown in an RxJS operator. These errors produce JavaScript ErrorEvent objects. The Angular assigns the ErrorEvent object to error property of the HttpErrorResponse.

In both the cases, the generic HttpErrorResponse is returned by the HTTP Module. We will inspect the error property to find out the type of Error and handle accordingly.

Catching Errors in HTTP Request

We can catch the HTTP Errors at three different places.

  1. Component
  2. Service
  3. Globally

Catch Errors in Component

Refer to our tutorial on Angular HTTP Get Request. We created a GitHubService, where we made a GET request to the GitHub API to get the list of Repositories. The following is the getRepos() method from the service. We have intentionally changed the URL (uersY) so that it will result in an error.

getRepos(userName: string): Observable<any> {

   return this.http.get(this.baseURL + ‘usersY/’ + userName + ‘/repos’)

}

We subscribe to the httpClient.get method in the component class

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

  public getRepos() {

    this.loading = true;

    this.errorMessage = «»;

    this.githubService.getReposCatchError(this.userName)

      .subscribe(

        (response) => {                           //Next callback

          console.log(‘response received’)

          this.repos = response;

        },

        (error) => {                              //Error callback

          console.error(‘error caught in component’)

          this.errorMessage = error;

          this.loading = false;

          //throw error;   //You can also throw the error to a global error handler

        }

      )

  }

The subscribe method has three callback arguments.

.subscribe(success, error, completed);

The observable invokes the first callback success, when the HTTP request successfully returns a response. The third call back completed is called when the observable finishes without any error.

The second callback error, is invoked when the HTTP Request end in an error. We handle error here by figuring out the type of error and handle it accordingly. It gets the error object which is of type HttpErrorResponse.

        (error) => {                              //Error callback

          console.error(‘error caught in component’)

          this.errorMessage = error;

          this.loading = false;

        }

Catch Errors in Service

We can also catch errors in the service, which makes the HTTP Request using the catchError Operator as shown below. Once you handle the error, you can re-throw it back to the component for further handling.

  getRepos(userName: string): Observable<repos[]> {

    return this.http.get<repos[]>(this.baseURL + ‘usersY/’ + userName + ‘/repos’)

      .pipe(

        catchError((err) => {

          console.log(‘error caught in service’)

          console.error(err);

          //Handle the error here

          return throwError(err);    //Rethrow it back to component

        })

      )

  }

Catch error globally using HTTP Interceptor

The type of error we may encounter vary. But some of those errors are common to every HTTP request. For Example

  1. You are unauthorized to access the API Service,
  2. You are authorized, but forbidden to access a particular resource
  3. The API End Point is invalid or does not exist
  4. Network error
  5. Server down

We can check all these errors in the service or in component, but our app may contain many such service or components. Checking for common errors in each and every method is inefficient and error-prone.

The Right thing to do is to handle only the errors specific to this API call in this component/service and move all the common errors to one single place. This is where we use the HTTP Interceptor.

The HTTP Interceptor is a service, which we create and register it globally at the root module using the Angular Providers. Once defined, it will intercept all the HTTP requests passing through the app. It intercepts when we make the HTTP request and also intercepts when the response arrives. This makes it an ideal place to catch all the common errors and handle it

We create the Interceptor by creating a Global Service class, which implements the HttpInterceptor Interface. Then we will override the intercept method in that service.

The following code shows a simple GlobalHttpInterceptorService

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

import {Injectable} from «@angular/core»;

import {HttpEvent, HttpHandler, HttpInterceptor,HttpRequest,HttpResponse,HttpErrorResponse} from ‘@angular/common/http’;

import {Observable, of, throwError} from «rxjs»;

import {catchError, map} from ‘rxjs/operators’;

@Injectable()

export class GlobalHttpInterceptorService implements HttpInterceptor {

  constructor(public router: Router) {

  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    return next.handle(req).pipe(

      catchError((error) => {

        console.log(‘error is intercept’)

        console.error(error);

        return throwError(error.message);

      })

    )

  }

}

The caching of the Error is done using the catchError RxJS operator. We then re-throw it to the subscriber using the throwError

The catchError is added to the request pipeline using the RxJs pipe operator . When the error occurs in the HTTP Request it is intercepted and invokes the catchError. Inside the catchError you can handle the error and then use throwError to throw it to the service.

We then register the Interceptor in the Providers array of the root module using the injection token HTTP_INTERCEPTORS. Note that you can provide more than one Interceptor (multi: true).

providers: [

    GitHubService,

    { provide: HTTP_INTERCEPTORS, useClass: GlobalHttpInterceptorService, multi: true  }

]

Next, step is what to do with the errors

The server-side errors return status codes, we can take appropriate actions based on that. For Example for Status code 401 Unauthorized, we can redirect the user to the login page, for 408 Request Timeout, we can retry the operation, etc.

The following example code shows how to check for status codes 401 & 403 and redirect to the login page.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

if (error instanceof HttpErrorResponse) {

    if (error.error instanceof ErrorEvent) {

        console.error(«Error Event»);

    } else {

        console.log(`error status : ${error.status} ${error.statusText}`);

        switch (error.status) {

            case 401:      //login

                this.router.navigateByUrl(«/login»);

                break;

            case 403:     //forbidden

                this.router.navigateByUrl(«/unauthorized»);

                break;

        }

    }

} else {

    console.error(«some thing else happened»);

}

return throwError(error);

For Server errors with status codes 5XX, you can simply ask the user to retry the operation. You can do this by showing an alert box or redirect him to a special page or show the error message at the top of the page bypassing the error message to a special service AlertService.

For other errors, you can simply re-throw it back to the service.

return throwError(error);

You can further handle the error in service or throw it back to the component.

The component must display the error message to the user. You can also throw it back to a global error handler in Angular.

.subscribe(

   (response) => {

      this.repos = response;

   },

   (error) => {

      //Handle the error here

      //If not handled, then throw it

      throw error;

   }

)

HTTP Error handling example

The complete code of this example

app.component.html

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

<h1 class=«heading»><strong>Angular HTTP</strong>Error Example</h1>

<div class=«form-group»>

  <label for=«userName»>GitHub User Name</label>

  <input type=«text» class=«form-control» name=«userName» [(ngModel)]=«userName»>

</div>

<div class=«form-group»>

  <button type=«button» (click)=«getRepos()»>Get Repos</button>

</div>

<div *ngIf=«loading»>loading...</div>

<div *ngIf=«errorMessage» class=«alert alert-warning»>

  <strong>Warning!</strong> {{errorMessage | json}}

</div>

<table class=‘table’>

  <thead>

    <tr>

      <th>ID</th>

      <th>Name</th>

      <th>HTML Url</th>

      <th>description</th>

    </tr>

  </thead>

  <tbody>

    <tr *ngFor=«let repo of repos;»>

      <td>{{repo.id}}</td>

      <td>{{repo.name}}</td>

      <td>{{repo.html_url}}</td>

      <td>{{repo.description}}</td>

    </tr>

  </tbody>

</table>

<pre>{{repos | json}}</pre>

app.component.ts

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

import { Component } from ‘@angular/core’;

import { GitHubService } from ‘./github.service’;

import { repos } from ‘./repos’;

@Component({

  selector: ‘app-root’,

  templateUrl: ‘./app.component.html’,

})

export class AppComponent {

  userName: string = «tektutorialshub»

  repos: repos[];

  loading: boolean = false;

  errorMessage;

  constructor(private githubService: GitHubService) {

  }

  public getRepos() {

    this.loading = true;

    this.errorMessage = «»;

    this.githubService.getReposCatchError(this.userName)

      .subscribe(

        (response) => {                           //Next callback

          console.log(‘response received’)

          this.repos = response;

        },

        (error) => {                              //Error callback

          console.error(‘error caught in component’)

          this.errorMessage = error;

          this.loading = false;

          throw error;

        }

      )

  }

}

github.service.ts

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

import { Injectable } from ‘@angular/core’;

import { HttpClient, HttpParams, HttpHeaders } from ‘@angular/common/http’;

import { Observable, throwError } from ‘rxjs’;

import { map, catchError } from ‘rxjs/operators’;

import { repos } from ‘./repos’;

@Injectable( {providedIn:‘root’})

export class GitHubService {

  baseURL: string = «https://api.github.com/»;

  constructor(private http: HttpClient) {

  }

  //Any Data Type

  getRepos(userName: string): Observable<any> {

    return this.http.get(this.baseURL + ‘usersY/’ + userName + ‘/repos’)

  }

  //With catchError

  getReposCatchError(userName: string): Observable<repos[]> {

    return this.http.get<repos[]>(this.baseURL + ‘usersY/’ + userName + ‘/repos’)

      .pipe(

        catchError((err) => {

          console.log(‘error caught in service’)

          console.error(err);

          return throwError(err);

        })

      )

  }

}

global-http-Interceptor.service.ts

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

import { Injectable } from «@angular/core»;

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpErrorResponse } from ‘@angular/common/http’;

import { Observable, of, throwError } from «rxjs»;

import { catchError, map } from ‘rxjs/operators’;

import { Router } from ‘@angular/router’;

@Injectable()

export class GlobalHttpInterceptorService implements HttpInterceptor {

  constructor(public router: Router) {

  }

  //1.  No Errors

  intercept1(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    return next.handle(req).pipe(

      catchError((error) => {

        console.log(‘error in intercept’)

        console.error(error);

        return throwError(error.message);

      })

    )

  }

  //2. Sending an Invalid Token will generate error

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    const token: string = ‘invald token’;

    req = req.clone({ headers: req.headers.set(‘Authorization’, ‘Bearer ‘ + token) });

    return next.handle(req).pipe(

      catchError((error) => {

        console.log(‘error in intercept’)

        console.error(error);

        return throwError(error.message);

      })

    )

  }

  intercept3(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    const token: string = ‘invald token’;

    req = req.clone({ headers: req.headers.set(‘Authorization’, ‘Bearer ‘ + token) });

    return next.handle(req).pipe(

      catchError((error) => {

        let handled: boolean = false;

        console.error(error);

        if (error instanceof HttpErrorResponse) {

          if (error.error instanceof ErrorEvent) {

            console.error(«Error Event»);

          } else {

            console.log(`error status : ${error.status} ${error.statusText}`);

            switch (error.status) {

              case 401:      //login

                this.router.navigateByUrl(«/login»);

                console.log(`redirect to login`);

                handled = true;

                break;

              case 403:     //forbidden

                this.router.navigateByUrl(«/login»);

                console.log(`redirect to login`);

                handled = true;

                break;

            }

          }

        }

        else {

          console.error(«Other Errors»);

        }

        if (handled) {

          console.log(‘return back ‘);

          return of(error);

        } else {

          console.log(‘throw error back to to the subscriber’);

          return throwError(error);

        }

      })

    )

  }

}

global-error-handler.service.ts

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

import { ErrorHandler, Injectable, Injector } from ‘@angular/core’;

import { HttpErrorResponse } from ‘@angular/common/http’;

import { throwError } from ‘rxjs’;

@Injectable()

export class GlobalErrorHandlerService implements ErrorHandler {

  constructor() {

  }

  handleError(error: Error | HttpErrorResponse) {

    console.log(‘GlobalErrorHandlerService’)

    console.error(error);

  }

}

app.module.ts

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

import { BrowserModule } from ‘@angular/platform-browser’;

import { NgModule ,ErrorHandler } from ‘@angular/core’;

import { HttpClientModule,HTTP_INTERCEPTORS} from ‘@angular/common/http’;

import { FormsModule } from ‘@angular/forms’;

import { AppComponent } from ‘./app.component’;

import { GlobalHttpInterceptorService} from ‘./global-http-Interceptor.service’;

import { AppRoutingModule } from ‘./app-routing.module’;

import { GlobalErrorHandlerService } from ‘./global-error-handler.service’;

@NgModule({

  declarations: [

    AppComponent

  ],

  imports: [

    BrowserModule,

    HttpClientModule,

    FormsModule,

    AppRoutingModule

  ],

  providers: [

    { provide: HTTP_INTERCEPTORS,    useClass: GlobalHttpInterceptorService,    multi: true  },

    { provide: ErrorHandler, useClass:GlobalErrorHandlerService}

],

  bootstrap: [AppComponent]

})

export class AppModule { }

app-routing.module.ts

import { NgModule } from ‘@angular/core’;

import { Routes, RouterModule } from ‘@angular/router’;

const routes: Routes = [];

@NgModule({

  imports: [RouterModule.forRoot(routes)],

  exports: [RouterModule]

})

export class AppRoutingModule { }

Angular HTTP Error Handling Example

References

HttpErrorResponse

Summary

Using HTTP Interceptors you can catch HTTP Errors and handle it appropriately. Check the HTTP status codes and take appropriate actions like redirecting to the login page, or redirecting to an error page or else throw the error back to the subscriber for further handling of the error.

Понравилась статья? Поделить с друзьями:

Не пропустите эти материалы по теме:

  • Яндекс еда ошибка привязки карты
  • Android ошибка приложение не установлено
  • Android ошибка подключения ssl
  • Android ошибка извлечения rar
  • Android ошибка com android camera

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии