角度拦截HTTP错误 [英] Angular intercepting http errors

查看:78
本文介绍了角度拦截HTTP错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想拦截每个请求和错误响应.

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.

但是我找不到拦截HttpErrorResponse的方法.

However I can't find a way to intercept HttpErrorResponse.

我尝试了2种方法.一个带有显式的rxjs catchError,另一个带有某种回调:

I tried 2 methods. One with an explicit rxjs catchError and the other with some kind of callback:

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

如果我有一个已过期的令牌,则每个请求都将引发HttpErrorResponse,但是此解决方案无法捕获它.

If I have an expired token, every request throws an HttpErrorResponse but this solution doesn't catch it.

这是由服务返回的.拦截器没有显示console.log()的迹象.

This is returned by the service. No sign of the console.log() from the interceptor.

服务如下:

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.

我见过人们( https://medium.com/@aleixsuau/error-handling-angular-859d529fa53a )在模块中注册一个ErrorHandler,但我还没有尝试过.

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.

如何从拦截器中捕获HttpErrorResponse?

How do I catch an HttpErrorResponse from my interceptor?

我尝试了ErrorHandler方法,但仍然无法获取任何日志.然后我从服务中删除了catchError并最终记录了一些内容...

I've tried the ErrorHandler way but still couldn't get any log. 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 :(

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

I made a reproducible example here: https://stackblitz.com/edit/angular-m2jc9n

推荐答案

Angular有一个用于错误处理的钩子( https://angular.io/api/core/ErrorHandler ).

Angular has a hook for error handling (https://angular.io/api/core/ErrorHandler).

您可以创建一个服务,该服务实现有角度的ErrorHandler并实现handleError方法,您可以在其中记录所有错误.该错误处理程序不仅会记录HttpErrorResponse,还会记录所有错误,但是您可以过滤掉所需的错误.

You can create a service which implements the angular ErrorHandler and implements handleError method where you can log all errors. This error handler would log not just HttpErrorResponse but all errors, but you can filter out the ones you need.

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

这篇关于角度拦截HTTP错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆