【问题标题】:Angular interceptor is altering the pipleline for erronous HTTP responsesAngular 拦截器正在更改错误 HTTP 响应的管道
【发布时间】:2019-11-27 13:55:11
【问题描述】:

我被要求修改现有的 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;
    }

【问题讨论】:

  • 你可以尝试为它创建一个演示吗?
  • 该演示需要我创建并公开一个真正的后端,因为当前的模拟在从前端调用它们时工作正常

标签: angular angular-http-interceptors


【解决方案1】:

在拦截函数中,你返回的是next.handle(reqCopy).pipe(,它不是Observable&lt;HttpEvent&lt;any&gt;&gt;的类型。

您需要按以下方式处理。

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

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-23
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    • 1970-01-01
    相关资源
    最近更新 更多