角度错误拦截器,在不同的URL上重试原始请求

时间:2019-05-03 12:03:37

标签: angular error-handling rxjs observable angular7

几个月前,我开始使用Angular进行一个新项目,但现在我需要编写一个更复杂的错误拦截器,以检测后端API何时关闭。

拦截器需要检测HTTP错误代码,如果服务器已关闭,则需要执行对第三方API服务器的请求,并获取可用后端服务器URL的列表,从该列表ping每个服务器,直到出现一个找到UP,然后重试原始请求(基本上是更改基本URL)。

拦截器需要执行以下步骤:

  1. 检查错误代码,如果错误代码为0,则调用该方法来处理问题
  2. 执行对其他API的请求,以获取所有可用服务器的列表
  3. 遍历列表并ping列表中的每个服务器。
  4. 找到可用服务器后,重试原始请求。

就我而言,通常的要求是获取项目列表:

getProjects() {
    return this.http.get<IProject[]>('/projects');
  }

缺少基本URL,因为我使用了另一个拦截器来动态添加它。

获取可用后端服务器URL列表的方​​法:

getRoutes() {
    return this.http.get<IRoute[]>(this.API_URL + '/routes');
  }

和可以ping服务的服务

ping(url: string) {
    return this.http.get(url, { observe: 'response', responseType: 'text' });
  }

直到这里一切都按预期运行。

现在是拦截器:

intercept(request, next) {
    return next.handle(request).pipe(
      catchError((error: any) => {
        if (error.status === 0) {
          return this.handleServerDownError(request, next);
        }
        return throwError(error);
      })
    );
  }

handleServerDownError(request, next) {
    return this.routesService.getRoutes().pipe(
      map(routes => {        
         routes.map((route: IRoute) =>
            this.pingService.ping(route.value).subscribe(res => {
              if (res.status === 200) {
                const updatedReq = request.clone({
                  url: route.value + request.url
                });
                return next.handle(updatedReq);
              }
            })
          );
      })
    );
  }

我几乎可以工作了,但是如果ping服务器关闭并且我收到相同的错误代码并且进入无穷循环,那么ping方法当然会返回相同的错误代码。

有什么想法可以使其生效吗?也许我可以更改ping方法返回不同的代码?

在找到第一个可用服务器之后,如何停止在map函数中进行迭代?

谢谢!

1 个答案:

答案 0 :(得分:1)

  

我几乎要工作了,但是ping方法当然会返回   如果ping通的服务器已关闭并且我收到相同的错误代码   错误代码,我进入了一个无限循环。

为此,您可以在ping网址的末尾添加一个虚拟路径(例如:http://something:8080/dummy_ping),以便可以确定它是否是您if条件中的ping请求。

if (error.status === 0 && !this.isDummyRequest(request)) {
  return this.handleServerDownError(request, next);
}
...
...

private isDummyRequest(request: HttpRequest<any>): boolean {
    if (request.url.includes('/dummy_ping')) {
      return true;
    } else {
      return false;
    }
}
  

在第一次调用后,如何停止在map函数中进行迭代   找到可用的服务器?

可以使用查找功能代替地图