angular8 interceptor拦截器影响接口单独进行error错误处理

294 阅读1分钟

请求错误,添加拦截器后,无法对接口进行单独错误处理,写法如下:

拦截器:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const newReq = req.clone({
        setHeaders: {
            'Cache-Control': 'no-cache',
            'Pragma': 'no-cache'
        }
    });
    return next.handle(newReq).pipe(
       catchError((err: HttpErrorResponse) => this.handleData(err))
    );
}


handleData(event: HttpResponse<any> | HttpErrorResponse): Observable<any> {
    switch (event.status) {
        case 401:
            ...
            return of(event);
        case 500:
        case 502:
            localStorage.removeItem('isLogin');
            return of(event);
        default:
            break;
    }
    return throwError(event);
}
问题:

在某些接口返回401时,需对报错接口特殊处理,使用其他url进行请求,而添加拦截器后,接口被拦截,无法进入err,如下:

getSystemInfo() 
        this.configService.getSystemInfo().subscribe((data: any) => {
            this.systemInfo = data;
            this.titleService.setTitle(this.systemInfo['productName']);
        }, (err) => {
            this.configService.getSystemCopy().subscribe((data: any) => {
                this.dealSystemInfo(data);
            });
        });
}
解决方案:

此时拦截器需要使用tap函数,RxJS 的 tap 操作符会捕获请求成功了还是失败了,拦截器修改如下:

 intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const newReq = req.clone({
        setHeaders: {
            'Cache-Control': 'no-cache',
            'Pragma': 'no-cache'
        }
    });
    return next.handle(newReq).pipe(
        tap(
           event => {
               // 允许统一对请求错误处理
                if (event instanceof HttpResponse ) {
                    this.handleData(event);
                } else {
                     // 若一切都正常,则后续操作
                    return event;
                }
           } , error => {
                if (error instanceof HttpErrorResponse) {
                    this.handleData(error);
                }
            }
        )
    );
}