Vous avez quelques options, en fonction de vos besoins. Si vous souhaitez gérer les erreurs sur une demande de base, ajouter un catch
à votre demande. Si vous souhaitez ajouter une solution globale, utilisez HttpInterceptor
.
Ouvrir ici le travail de démonstration plunker pour les solutions ci-dessous.
tl;dr
Dans le cas le plus simple, vous avez juste besoin d'ajouter un .catch()
ou .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.
Méthode (local) solution: journal d'erreur et le retour de secours réponse
Si vous avez besoin pour gérer les erreurs dans un seul endroit, vous pouvez utiliser catch
et de retourner une valeur par défaut (ou de réponse vide) au lieu d'échouer complètement. Vous pouvez aussi ne pas besoin de l' .map
seulement de jeter, vous pouvez utiliser une fonction générique. Source: Angulaire.io - Obtenir des Détails de l'Erreur.
Donc, un générique .get()
méthode, serait de:
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 manipulation de l'erreur vous permettra d'application à continuer même si le service à l'adresse URL est en mauvais état.
Cette par-requête solution est bonne la plupart du temps quand vous voulez retourner un spécifique de réponse par défaut à chaque méthode. Mais si vous ne se soucient que l'erreur d'affichage (ou qui ont un global de réponse par défaut), la meilleure solution est d'utiliser un intercepteur, comme décrit ci-dessous.
Exécuter le travail de démonstration plunker ici.
Utilisation avancée: Intercepter toutes les requêtes ou réponses
Une fois de plus, Angulaire.io guide montre:
L'une des caractéristiques majeures de l' @angular/common/http
est l'interception, la possibilité de déclarer des intercepteurs qui siègent dans l'entre votre application et le backend. Lorsque votre application effectue une demande, les intercepteurs de la transformer avant de les envoyer au serveur, et les intercepteurs peuvent transformer la réponse sur son chemin de retour avant que votre demande ne la voit. C'est utile pour tout, de l'authentification à la connexion.
Ce qui, bien sûr, peut être utilisé pour gérer les erreurs d'une 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>>();
});
}
}
En fournissant votre intercepteur: le simple fait de déclarer l' HttpErrorInterceptor
ci-dessus n'est pas la cause de votre application pour l'utiliser. Vous avez besoin de fil dans votre application module en fournissant comme un 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 avez à la fois une erreur de l'intercepteur et de la gestion des erreurs, naturellement, il est probable qu'aucune erreur de manipulation ne sera jamais déclenché, depuis que l'erreur sera toujours gérée par l'intercepteur avant qu'il atteigne le local d'erreur de manipulation.
Exécuter le travail de démonstration plunker ici.