2017-07-28 54 views
7

我想,以便相应地做出反应拦截401和其他错误。这是我的拦截器:HttpInterceptor在角4.3:拦截400个错误响应

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

虽然这非常适用于200名的请求,不拦截错误respsonses

所有我在Chrome的开发者控制台中看到的是这样的:

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

或者这

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

我会像我的拦截器来处理这一点。我错过了什么?

回答

17

Http将错误向下发送到observable的错误流中,因此您需要用.catch来捕获它们(您可以阅读关于此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

好吧,但是这给了我这个错误:[ts] 类型'(err:any)=> void'的参数不能分配给类型为'(err:any,caught:Observable >)=> ObservableInput <{}>'。 类型'void'不可分配为键入'ObservableInput <{}>'。 – Tim

+0

添加“return Observable.throw(err);”解决了这个问题。编辑你的答案,我会接受它! – Tim

+0

@Tim喜欢吗?对不起,我没有在发布之前对它进行测试:) – 0mpurdy

4

这可能是为时已晚供您使用,但希望别人会发现它很有用...这是如何改写上述return语句记录错误的反应,太:

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

我使用相同的方法学来自动直接发送到我们的注销方法的所有401点未授权的响应(而不是在每次调用HTTP检查401):

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

它的工作原理LIK绝对的魅力。 :)

+0

如果发生错误我要记录错误但仍然返回HttpResponse以便Angular客户端可以在用户界面上显示错误消息? –

+0

如果你的意思是“HttpErrorResponse”(而不是HttpResponse),我的回复中的第一个例子就是这个例子。记录成功响应和错误响应,然后传递,就好像根本没有拦截器一样。 – Enrika

+0

我无法收到验证错误。 – Velkumar