Angular 拦截器正在改变错误 HTTP 响应的管道

Angular interceptor is altering the pipleline for erronous HTTP responses

我被要求修改一个现有的 angular http 拦截器,特别是添加一个逻辑以在对 API 的请求失败时在开发人员控制台中显示错误。

在阅读了一些关于它的文章后,我读到在响应中使用 pipe 结合 tap 我可以使用 catchError 来显示它。

那部分工作正常,但似乎管道受到了影响,因为即使我在 catchError 函数上返回错误的 Observable,该值也没有返回到此管道的接收端(即在 API 调用中使用订阅时)

这里是我手上的拦截器的相关代码

我做错了什么影响了管道?为什么现有代码没有收到错误,即使我正在返回它们。

intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
    if (!this.isRefreshingToken) {
      // not relevant logic
    }

    const reqCopy = this.addHeaderToRequest(req);

    // continue the request flow and tap into the response
    return next.handle(reqCopy).pipe(
      tap(evt => {
        if (evt instanceof HttpResponse) {
          if (evt.status === 500) {
            console.log(">>", evt.body);
          }
        }
      }),
      catchError((err: any) => {
        /* in case a special logic is neeeded for HttpErrorResponse
        if(err instanceof HttpErrorResponse) {

        }
        */
       console.error(err) ;

       if(!!err.error) {
        console.error(JSON.stringify(err.error));
       }

        // return an observable of the error as required by the pipeline
        return of(err);
      })
    );
}

这里是调用API的代码,以前是可以工作的,意思是当调用后端时收到错误时执行//login failed逻辑,但现在这个逻辑不是了正在执行,为此和许多其他 api 调用。

this.service.login(this.model).subscribe(
  // login successful
  () => {
      //not relevant code
  },
  // login failed
  error => {
    this.ssoService.init();
    console.log("Login error: ", error);
    switch (error.originalError.status) {
      case 307: 
        // need password change
        break;
      case 400:
        this.notificationService.showError(
          NotificationMessages.LoginUserOrPasswordIncorrect
        );
        break;
      case 423:
        this.error = NotificationMessages.LoginAccountLocked;
        break;
      case 404:
        this.notificationService.showError(
          NotificationMessages.LoginUserOrPasswordIncorrect
        );
        break;
      default:
        break;
    }

在拦截函数中,您返回的是 next.handle(reqCopy).pipe(,这不是 Observable<HttpEvent<any>>.

的类型

您需要按以下方式处理

intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {

    const reqCopy = req;

    // continue the request flow and tap into the response
    const event = next.handle(reqCopy);
    event.pipe(
      tap(evt => {
        // ... your code
      }),
      catchError((err: any) => {
          //....... your code
        return of(err);
      })
    );

    return event;
}

这是演示 - https://stackblitz.com/edit/angular-interceptors-8aygw4

希望对您有所帮助。