w tym samouczku zapoznasz się z błędami HTTP w JavaScript i jak korzystać z HttpClient z operatorami obsługi błędów RxJS i wreszcie jak korzystać z HttpInterceptor

jest to głębokie nurkowanie w obsłudze błędów HTTP w Angular 7, możesz sprawdzić wpis wprowadzający na temat obsługi błędów tutaj.

wymagania wstępne

aby móc wykonać demonstrację tego samouczka, powinieneś mieć:

  • węzeł w wersji 11.0 zainstalowany na twoim komputerze.
  • Node Package Manager w wersji 6.7 (zwykle jest dostarczany z instalacją węzła).
  • Angular CLI Wersja 7.0
  • najnowsza wersja Angular (wersja 7)
 // run the command in a terminal ng version

potwierdź, że używasz wersji 7 i zaktualizuj ją do 7, jeśli nie.Inne rzeczy, które będą mile widziane to:

  • praktyczna znajomość frameworka Angular na poziomie początkującym.
  • znajomość usług Angular będzie plusem, ale nie wymogiem.

błędy Outsider

są to błędy, które nazywamy błędami po stronie serwera, ponieważ pochodzą one głównie z zewnątrz aplikacji Angular iHttpErrorResponse jest zawsze zwracany w każdej chwili, gdy występują. Ma właściwości takie jak:

  • nazwa błędu: określa nazwę błędu.
  • komunikat o błędzie: to próbuje wyjaśnić błąd w prostych słowach dla łatwiejszego zrozumienia.
  • status błędu: każdy typ błędu po stronie serwera ma przypisany kod, aby odróżnić go od reszty. Kody te są zwykle trzycyfrowymi kodami, takimi jak 400, co oznacza, że wysłane żądanie było nieoczekiwane lub 500, które sygnalizuje wewnętrzny błąd serwera i tak dalej.

obsługa błędów w Angular

Angular ma globalną klasę obsługi błędów o nazwie errorHandler, która zapewnia hook do scentralizowanej obsługi wyjątków wewnątrz aplikacji. Zasadniczo przechwytuje wszystkie błędy, które zdarzają się w aplikacji, i rejestruje je wszystkie na konsoli, i zatrzymuje aplikację przed awarią.Składnia wygląda tak:

 class MyErrorHandler implements ErrorHandler { handleError(error) { // do something with the exception } } @NgModule({ providers: }) class MyModule {}

jest to świetny sposób na obsługę błędów w Angular, szczególnie błędów insider.

ograniczenie errorHandler

Jeśli podążyłeś za tym wpisem wprowadzającym, zobaczysz, jak Klasa Angular errorHandler była najlepszym rozwiązaniem do centralizacji koncepcji try/catch błędów w naszej aplikacji. Jednakże, gdy chcemy skupić się na błędach po stronie serwera, odkrywamy, że klasa errorHandler nie może pracować bezpośrednio z żądaniami HTTP w naszej aplikacji. Dobrą wiadomością jest to, że Angular dostarcza swego rodzaju interfejs, w którym można użyć koncepcji klasy errorHandler do bezpośredniej obsługi żądań HTTP.

rozwiązanie 1: Angular HttpClient

(https://angular.io/api/common/http/HttpClient) w@angular/common/``(https://angular.io/api/common/http) oferuje uproszczone API klienta HTTP dla aplikacji kątowych, które opiera się naXMLHttpRequest interfejs narażony przez przeglądarki. Dodatkowe zalety (https://angular.io/api/common/http/HttpClient)obejmują funkcje testowalności, wpisane obiekty żądania i odpowiedzi, przechwytywanie żądania i odpowiedzi, Observable API i usprawnioną obsługę błędów. Tak więc używając tego klienta z niektórymi operatorami RxJS możemy uzyskać rodzaj try / catch sposobu obsługi błędów, ale tym razem bezpośrednio komunikując się z żądaniami HTTP za pośrednictwem aplikacji Angular w usłudze. Zrozumiesz to lepiej w działaniu.

Demo

jest to aplikacja demonstracyjna jsonplaceholder, w której części dostępnych danych na jsonplaceholder są wyświetlane w interfejsie użytkownika, doskonała usługa do demonstrowania pojęć związanych z serwerem. Jeśli masz wszystkie warunki wstępne podane na początku postu gotowe, możesz pobrać projekt z GitHub tutaj. Rozpakuj i otwórz projekt w kodzie VS i użyj terminala do inicjalizacji modułów węzła:

 npm install

teraz, gdy Twoja aplikacja jest uruchomiona, musisz przede wszystkim upewnić się, że moduł wymagany do aplikacji Angular do korzystania z dowolnej usługi serwera jest aktywny w Twojej aplikacji. Przejdź do plikuapp.module.ts i potwierdź, że istnieje polecenie importu takie jak:

 import { HttpClientModule } from '@angular/common/http';

Twoja aplikacja składa się z czterech komponentów: postów, paska bocznego, szczegółów i użytkowników. Posiada również usługę o nazwie data service, w której wykonywane są wszystkie żądania HTTP. Twój plikdata.service.ts powinien wyglądać tak:

 // src/app/services/data.service.ts import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class DataService { constructor(private http: HttpClient) { } getUsers() { return this.http.get('https://jsonplaceholder.typicode.com/users') } getUser(userId) { return this.http.get('https://jsonplaceholder.typicode.com/users/'+userId) } getPosts() { return this.http.get('https://jsonplaceholder.typicode.com/posts') } }

trzy żądania są wysyłane do serwera, teraz jeśli wybierzesz jedno z tych żądań, powiedzgetUsers() I chcesz dodać obsługę błędów za pomocą HttpClient, wtedy będziesz:

  • Import obiektu catchError z operatorów RxJS.
  • Importuj throwError z RxJS.
  • użyj metody pipe, aby wprowadzić ją do żądanego żądania HTTP.
  • Utwórz metodę obsługi błędu

jeśli zastosujesz się do nich, Twój plik data.service.ts będzie wyglądał następująco:

 // src/app/services/data.service.ts import { Injectable } from '@angular/core'; import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { catchError } from 'rxjs/operators' import { throwError } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class DataService { constructor(private http: HttpClient) { } getUsers() { return this.http.get('https://jsonplaceholder.typicode.com/usssers') .pipe( catchError(this.handleError) ); } getUser(userId) { return this.http.get('https://jsonplaceholder.typicode.com/users/'+userId) } getPosts() { return this.http.get('https://jsonplaceholder.typicode.com/posts') } handleError(error: HttpErrorResponse){ console.log("lalalalalalalala"); return throwError(error); } }

zobaczysz, że żądanie get zostało celowo zmodyfikowane, aby upewnić się, że wystąpił błąd. Po uruchomieniu aplikacji, pojawi się błąd zalogowany z Komunikatem dziennika chcemy.

czasami, gdy wysyłasz żądanie na dobrze znany powolny serwer, wiesz, że uzyskanie odpowiedzi może trochę potrwać lub zająć kilka prób uzyskania odpowiedzi z serwera, możesz ponownie wysłać żądanie kilka razy przed wyrzuceniem błędu. Można to osiągnąć za pomocą metody retry w RxJS, więc importujesz Operator retry, a następnie możesz użyć go wewnątrz rury tak, jak jest to używane poniżej:

 // src/app/services/data.service.ts import { Injectable } from '@angular/core'; import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { catchError, retry } from 'rxjs/operators' import { throwError } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class DataService { constructor(private http: HttpClient) { } getUsers() { return this.http.get('https://jsonplaceholder.typicode.com/usssers') .pipe( retry(2), catchError(this.handleError) ); } getUser(userId) { return this.http.get('https://jsonplaceholder.typicode.com/users/'+userId) } getPosts() { return this.http.get('https://jsonplaceholder.typicode.com/posts') } handleError(error: HttpErrorResponse){ console.log("lalalalalalalala"); return throwError(error); } }

jeśli uruchomisz aplikację, konsola powinna wyglądać tak:

widzisz, że najpierw próbuje uzyskać odpowiedź, a następnie powtarza go dwa razy tak, jak określiliśmy przed wyrzuceniem komunikatu dziennika błędów.

bardzo ważne jest również, aby ponowić próbę przed catchError, aby Komunikat o błędzie nie był rejestrowany po każdej próbie.

To rozwiązanie działa idealnie, o ile Twoja aplikacja ma jedną usługę i prawdopodobnie jedno żądanie, ale gdy aplikacja jest duża i ma wiele usług lub dużo więcej żądań na usługę, staje się nieefektywnym rozwiązaniem. Dzieje się tak dlatego, że zawsze musisz skopiować funkcję błędu obsługi w różnych usługach i powtórzyć Kod nawet w ramach usługi. Wyobraź sobie koszt pamięci debugowania i utrzymywania bazy kodu.

najlepsza opcja: Angular HttpInterceptor

podobnie jak sama nazwa wskazuje, Angular zapewnia interfejs o nazwie HttpInterceptor, który może przechwytywać (https://angular.io/api/common/http/HttpRequest)I (https://angular.io/api/common/http/HttpResponse) I tworzy platformę do ich obsługi. Oznacza to, że mamy bezpośredni dostęp do żądań naszego serwera, co lepsze miejsce do radzenia sobie z błędami serwera niż tutaj!Składnia wygląda tak:

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

aby użyć HttpInterceptor, Utwórz nową usługę, w której chcesz, aby logika przechwytująca weszła z Angular CLI:

 ng generate service services/interceptor

teraz wygenerowałeś usługę przechwytującą, przejdź do pliku app.module.ts, aby go odpowiednio zarejestrować, w następujący sposób:

 // src/app/app.module.ts import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { UsersComponent } from './components/users/users.component'; import { DetailsComponent } from './components/details/details.component'; import { PostsComponent } from './components/posts/posts.component'; import { SidebarComponent } from './components/sidebar/sidebar.component'; import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations' import { InterceptorService } from './services/interceptor.service'; @NgModule({ declarations: , imports: , providers: , bootstrap: }) export class AppModule { }

następnym krokiem jest pozbycie się całej logiki obsługi błędów w data.service.ts plik, plik powinien wyglądać tak, gdy skończysz:

 // src/app/services/data.service.ts import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class DataService { constructor(private http: HttpClient) { } getUsers() { return this.http.get('https://jsonplaceholder.typicode.com/usersss') } getUser(userId) { return this.http.get('https://jsonplaceholder.typicode.com/users/'+userId) } getPosts() { return this.http.get('https://jsonplaceholder.typicode.com/posts') } }

skopiuj poniższy kod do interceptor.service.ts plik:

 // src/app/services/interceptor.service.ts 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({ providedIn: 'root' }) export class InterceptorService implements HttpInterceptor{ constructor() { } handleError(error: HttpErrorResponse){ console.log("lalalalalalalala"); return throwError(error); } intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{ return next.handle(req) .pipe( catchError(this.handleError) ) }; }

jeśli uruchomisz aplikację, możesz zobacz, że rejestruje nasz komunikat o błędzie i wyrzuca błąd tak, jak tego oczekujemy. Jest to najlepsza metoda obsługi błędów serwera w projekcie Angular. Możesz przetestować wszystkie trzy żądania na raz pod kątem błędów, manipulując nimi. Kiedy to zrobisz, dowiesz się, że interceptor łapie je wszystkie i rejestruje naszą wiadomość dla każdego, to naprawdę niesamowite oglądać.

wnioski

zapoznałeś się z różnymi sposobami obsługi błędów po stronie serwera w aplikacjach Angular. Widziałeś również, kiedy używać, a kiedy nie używać HttpClient z operatorami RxJS i jak najlepszym sposobem jest używanie przechwytywaczy. W następnym samouczku z tej serii zapoznasz się ze śledzeniem błędów. Pełny kod tego samouczka znajduje się na Githubie i można go znaleźć tutaj. Szczęśliwego kodowania!

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.