angular 7 中的 HTTPInterceptor 行为异常

HTTPInterceptor in angular 7 is behaving strangely

我有一个非常简单的拦截器,可以拦截错误并在控制台上打印输出:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
        catchError((error: HttpErrorResponse) => {
            if (error.status == 401) {
                console.log("Error 401", error);
            }
            else if (error.status == 404) {
                console.log("Error 404", error);
            }
            else if (error.status == 0) {
                console.log("Unknown error", error);
                sendRequestAgain();
            } else{
               // do nothing
            }
            return throwError(error)
        })
    );
}

问题是,当我得到 error.status==0 时,它第一次完美运行并再次发送请求(使用 sendRequestAgain()),但是当第二次请求失败时,错误被正确拦截,但控件没有进入 else if (error.status == 0) { 块。相反,它会下降到 else 块。我已经打印出错误,并且两次都完全相同。即使是 else if (error.status == 0) { 上的断点也没有第二次命中,这很奇怪。

有什么想法吗?

您可以尝试合并地图并检查错误是否是您要重试的错误,在这种情况下我使用 404,如果是,您在处理下一个请求之前设置 rxjs 计时器,最后在之后使用运算符 take 设置重试连接的时间。如果错误不是您想要重试的错误,那么只需再次返回错误并像以前没有发生过一样处理它。

import { Injectable } from '@angular/core';
import {
  HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse
} from '@angular/common/http';

import {Observable, throwError, timer} from 'rxjs';
import {catchError, mergeMap, retryWhen, take} from 'rxjs/operators';

@Injectable()
export class EnsureHttpsInterceptor implements HttpInterceptor {

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      retryWhen(errors => {
        return errors
          .pipe(
            mergeMap(error => error.status === 404 ? timer(5000) : throwError(error)),
            take(2)
          );
      }),
      catchError((error: HttpErrorResponse) => {

        switch (error.status) {
          case 401:
            console.log('Error 401', error);
            break;
          case 404:
            console.log('404', error);
            break;
          default:
            return throwError(error);
        }

      })
    );
  }
}