2017-07-28 9 views
7

Ich möchte abfangen 401 und andere Fehler, um entsprechend zu reagieren. Das ist mein Interceptor:HttpInterceptor in Angular 4.3: Abfangen 400 Fehler Antworten

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); 
       } 
      }); 
    } 
} 

Während dies gut für 200 Anfragen arbeitet, es nicht abfangen der Fehler respsonses

Alles, was ich in den Chrome-Entwickler-Konsole zu sehen, ist dies:

zone.js:2616 GET http://localhost:8080/backend/rest/wrongurl 404 (Not Found)

Oder das

zone.js:2616 GET http://localhost:8080/backend/rest/url 401 (Unauthorized)

ich würde wie mein Abfangjäger, um damit umzugehen. Was vermisse ich ?

Antwort

17

Http sendet Fehler in den Fehlerstrom einer Observable, so dass Sie sie mit .catch fangen müssen (Sie können mehr darüber lesen here).

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); 
    }); 
+0

Ok, aber das gibt mir diese Fehlermeldung: [ts] Argumente vom Typ '(err: any) => void' ist zu Parametern des Typs nicht belegbar ‚(err: beliebig, gefangen: Observable >) => ObservableInput <{}> '. Typ 'void' ist nicht dem Typ 'ObservableInput <{}>' zuweisbar. – Tim

+0

Hinzufügen von "return Observable.throw (err);" behebt das Problem. Bearbeite deine Antwort und ich akzeptiere sie! – Tim

+0

@tim so? Tut mir leid, ich habe es nicht getestet, bevor Sie posten :) – 0mpurdy

4

Dies ist wahrscheinlich für Sie viel zu spät ist, zu verwenden, aber hoffentlich jemand anderes wird es nützlich finden ... Dies ist, wie die oben return-Anweisung neu zu schreiben Fehlerreaktionen zu protokollieren, zu:

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); 
    } 
}); 

ich diese gleiche Methode bin mit automatisch alle 401 Unauthorized Antworten direkt an unser Abmeldeverfahren senden (und nicht bei jedem einzelnen Anruf zu http für eine 401-Prüfung):

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(); 
    } 
    } 
}); 

Es funktioniert lik E ein absoluter Charme. :)

+0

Was ist, wenn im Falle eines Fehlers möchte ich den Fehler protokollieren, aber immer noch eine HttpResponse, so dass der Angular-Client konnte die Fehlermeldung auf der Benutzeroberfläche anzeigen? –

+0

Wenn Sie "HttpErrorResponse" in Ihrer Frage (und nicht HttpResponse) gemeint haben, zeigt das erste Beispiel in meiner Antwort genau das. Sowohl die Erfolgsantworten als auch die Fehlerreaktionen werden protokolliert und dann weitergeleitet, als ob überhaupt kein Interzeptor vorhanden wäre. – Enrika

+0

Ich konnte meine Validierungsfehler nicht empfangen. – Velkumar