Vous avez quelques options, en fonction de vos besoins. Si vous souhaitez gérer les erreurs sur une base par demande, ajoutez un catch
à votre demande. Si vous souhaitez ajouter une solution globale, utilisez HttpInterceptor
.
Ouvrez ici le plunker de démonstration fonctionnel pour les solutions ci-dessous.
tl; dr
Dans le cas le plus simple, il vous suffira d'ajouter un .catch()
ou un .subscribe()
, comme:
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)
);
Mais il y a plus de détails à ce sujet, voir ci-dessous.
Solution de méthode (locale): erreur de journal et retour de réponse de secours
Si vous devez gérer des erreurs à un seul endroit, vous pouvez utiliser catch
et renvoyer une valeur par défaut (ou une réponse vide) au lieu d'échouer complètement. Vous n'avez pas non plus besoin de .map
simplement cast, vous pouvez utiliser une fonction générique. Source: Angular.io - Obtenir les détails de l'erreur .
Donc, une .get()
méthode générique , serait comme:
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>();
});
}
}
La gestion de l'erreur permettra à votre application de continuer même lorsque le service à l'URL est en mauvais état.
Cette solution par demande convient surtout lorsque vous souhaitez renvoyer une réponse par défaut spécifique à chaque méthode. Mais si vous ne vous souciez que de l'affichage des erreurs (ou si vous avez une réponse globale par défaut), la meilleure solution est d'utiliser un intercepteur, comme décrit ci-dessous.
Exécutez le plunker de démonstration fonctionnel ici .
Utilisation avancée: intercepter toutes les demandes ou réponses
Une fois de plus, le guide Angular.io montre:
Une caractéristique majeure de @angular/common/http
est l'interception, la possibilité de déclarer des intercepteurs qui se trouvent entre votre application et le backend. Lorsque votre application fait une demande, les intercepteurs la transforment avant de l'envoyer au serveur, et les intercepteurs peuvent transformer la réponse à son retour avant que votre application ne la voie. Ceci est utile pour tout, de l'authentification à la journalisation.
Ce qui, bien sûr, peut être utilisé pour gérer les erreurs de manière très simple ( démo plunker ici ):
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>>();
});
}
}
Fournir votre intercepteur: le simple fait de déclarer ce qui HttpErrorInterceptor
précède ne provoque pas son utilisation par votre application. Vous devez le connecter dans votre module d'application en le fournissant en tant qu'intercepteur, comme suit:
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 {}
Remarque: si vous disposez à la fois d' un intercepteur d'erreur et d'une gestion des erreurs locale, il est bien entendu probable qu'aucune gestion d'erreur locale ne sera jamais déclenchée, car l'erreur sera toujours gérée par l'intercepteur avant d' atteindre la gestion d'erreur locale.
Exécutez le plunker de démonstration fonctionnel ici .
return this.httpClient.get<type>(...)
. et ensuite avoircatch...
quelque part hors du service où il le consomme réellement parce que c'est là qu'il construira un flux d'observables et qu'il pourra le gérer le mieux.