Je voudrais que intercepte 401 et d'autres erreurs afin de réagir en conséquence. Ceci est mon intercepteur:
import { LoggingService } from './../logging/logging.service';
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
@Injectable()
export class TwsHttpInterceptor implements HttpInterceptor {
constructor(private logger: LoggingService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.logger.logDebug(request);
return next.handle(request)
.do(event => {
if (event instanceof HttpResponse) {
this.logger.logDebug(event);
}
});
}
}
Bien que cela fonctionne bien pour 200 demandes, il n'intercepte pas les réponses d'erreur
Tout ce que je vois dans la console de développement de chrome est la suivante:
zone.js: 2616 GET http: // localhost: 8080/backend/rest/wrongurl 404 (Non Trouvé)
Ou ca
zone.js: 2616 GET http: // localhost: 8080/backend/rest/url 401 (Non autorisé)
Je voudrais que mon intercepteur traite de cela. Qu'est-ce que je rate ?
Http
envoie des erreurs dans le flux d'erreur d'une observable, vous devrez donc les attraper avec .catch
(vous pouvez en savoir plus à ce sujet ici ).
return next.handle(request)
.do(event => {
if (event instanceof HttpResponse) {
this.logger.logDebug(event);
}
})
.catch(err => {
console.log('Caught error', err);
return Observable.throw(err);
});
C’est probablement trop tard pour vous, mais une autre personne trouvera cela utile. Voici comment réécrire la déclaration ci-dessus pour consigner les réponses aux erreurs:
return next.handle(request).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
this.logger.logDebug(event);
}
}, (error: any) => {
if (error instanceof HttpErrorResponse) {
this.logger.logDebug(error);
}
});
J'utilise cette même méthode pour envoyer automatiquement toutes les réponses 401 non autorisées directement à notre méthode de déconnexion (plutôt que de rechercher un 401 à chaque appel individuel vers http):
return next.handle(request).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// process successful responses here
}
}, (error: any) => {
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
authService.logout();
}
}
});
Cela fonctionne comme un charme absolu. :)
A l'époque, j'essayais Angular 7+.
Malheureusement les solutions ci-dessus n'ont pas bien servi le travail car
.do
n'est pas directement disponible surHttpHandler
à partir de la notion de RxJs 6 pipes; et la conversion deObservable to Promise
ne colle pas.
Voici une approche propre et à jour; Je pipe
l'opérateur catchError
et analyser l'erreur et enfin le relancer à l'aide de throwError
. Voici la forme finale de l'intercepteur;
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError((error: HttpErrorResponse) => {
if (error.error instanceof ErrorEvent) {
// client-side error or network error
} else {
// TODO: Clean up following by introducing method
if (error.status === 498) {
// TODO: Destroy local session; redirect to /login
}
if (error.status === 401) {
// TODO: Permission denied; show toast
}
}
return throwError(error);
})
);
}
Espérons que cette solution aidera quelqu'un à l'avenir.
Pour intercepter l'erreur de réponse HTTP dans l'angle 6, je fais un petit tour en convertissant Observable en Promesse:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const obs = next.handle(req);
if (!window.navigator.onLine) {
// Handle offline error
this.messageService.showError('No Internet Connection');
return;
}
obs.toPromise().catch((error) => {
this.messageService.progress(false);
this.messageService.showError(error.message);
});
return obs;
}