简体   繁体   English

角度拦截HTTP错误

[英]Angular intercepting http errors

I want to intercept each request and error responses. 我想拦截每个请求和错误响应。

I already can intercept requests and set a token in the headers and I can intercept the responses to handle a refresh token. 我已经可以拦截请求并在标头中设置令牌,并且可以拦截响应以处理刷新令牌。

However I can't find a way to intercept HttpErrorResponse . 但是我找不到拦截HttpErrorResponse

I tried 2 methods. 我尝试了2种方法。 One with an explicit rxjs catchError and the other with some kind of callback: 一个带有显式的rxjs catchError,另一个带有某种回调:

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const authToken = this.auth.getToken();
    if (authToken) {
      req = req.clone({ headers: req.headers.set('accesstoken', authToken) });
    }
    return next.handle(req).pipe(
      map((event: HttpEvent<any>) => {
        if (event instanceof HttpResponse) {
          //handle refresh token
        }
        return event;
      },
      catchError((error: any) => {
        if (error instanceof HttpErrorResponse) {
          console.log(error);
          return Observable.throw(error);
        }
      })));
  }

If I have an expired token, every request throws an HttpErrorResponse but this solution doesn't catch it. 如果我有一个已过期的令牌,则每个请求都将抛出HttpErrorResponse,但是此解决方案无法捕获该错误。

在此处输入图片说明

This is returned by the service. 这是由服务返回的。 No sign of the console.log() from the interceptor. 拦截器没有显示console.log()的迹象。

The service looks like this: 该服务如下所示:

public getData(): Observable<any> {
    return this.http
        .get<any>(url)
        .pipe(
            map(res => {
                return res;
            }),
            catchError((e): Observable<any> => {
                console.log(e);
                const res: any = {error: e};
                return of(res);
            })
        );
}

Then I tried with a "callback syntax": 然后,我尝试使用“回调语法”:

return next.handle(req).pipe(
  map((event: HttpEvent<any>) => {
    if (event instanceof HttpResponse) {
      // refresh token
    }
    return event;
  }, (error: any) => {
    if (error instanceof HttpErrorResponse) {
      console.log(error);
    }
  }));

Same result as above. 与上述相同的结果。 Nothing in the console. 控制台中没有任何内容。

I've seen people ( https://medium.com/@aleixsuau/error-handling-angular-859d529fa53a ) register an ErrorHandler in the module but I haven't tried it yet. 我见过人们( https://medium.com/@aleixsuau/error-handling-angular-859d529fa53a )在模块中注册ErrorHandler,但是我还没有尝试过。

How do I catch an HttpErrorResponse from my interceptor? 如何从拦截器捕获HttpErrorResponse?

EDIT: 编辑:

I've tried the ErrorHandler way but still couldn't get any log. 我已经尝试过ErrorHandler方法,但仍然无法获取任何日志。 Then I removed the catchError from my service and finally got something logged... 然后我从服务中删除catchError ,最后记录了一些内容...

I'll try to see if this makes the interceptor work... Not fun if I have to remove all my catchError :( 我将尝试看看这是否使拦截器正常工作...如果我必须删除所有catchError :(

I made a reproducible example here: https://stackblitz.com/edit/angular-m2jc9n 我在这里做了一个可复制的示例: https : //stackblitz.com/edit/angular-m2jc9n

Angular has a hook for error handling ( https://angular.io/api/core/ErrorHandler ). Angular有一个用于错误处理的钩子( https://angular.io/api/core/ErrorHandler )。

You can create a service which implements the angular ErrorHandler and implements handleError method where you can log all errors. 您可以创建一个服务,该服务实现有角度的ErrorHandler并实现handleError方法,您可以在其中记录所有错误。 This error handler would log not just HttpErrorResponse but all errors, but you can filter out the ones you need. 该错误处理程序不仅会记录HttpErrorResponse,还会记录所有错误,但是您可以过滤掉所需的错误。

@Injectable()
export class CustomErrorHandler implements ErrorHandler {
    private static isHttpErrorResponse(error): error is HttpErrorResponse {
        return error instanceof HttpErrorResponse;
    }

    handleError(error: any): void {
        if (CustomErrorHandler.isHttpErrorResponse(error)) {
            console.log(error);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM