中间停一根管子

Stop a pipe in the middle

在我的 angular 应用程序中,我有一个令牌刷新拦截器,它拦截 401-Unauthorized 错误,尝试刷新访问令牌,并再次执行原始 http 请求。

令牌刷新端点在某些情况下也可能失败,并且 return 已知错误(在我的例子中是 400 invalid_grant 错误)。

拦截器刷新令牌的部分:

 return this.httpClient
  .request('POST', "token", { observe: 'response' })
  .pipe(
    map(response => {
      // some logic when the token was refreshed successfully
    }),
    catchError(err => {
      this.routingService.navigateToLoginNoQuery();
      return throwError(err); // a 400 - invalid_grant error
    })
  );

发生这种情况时,它会进入一个 catchError 运算符,它会做两件事:注销(重定向到登录页面)和 returns throwError(error),它抛出的这个错误是 400-Invalid_grant错误。

这会导致新错误到达最初触发刷新令牌的函数中的某些 catchError 运算符。

仅供参考: 我在 catch 块中记录错误,我想避免记录此类错误,因为它们通常只表示用户的令牌已过期。

我想做的是以某种方式停止这个操作链,然后重定向到登录页面。

是否可以在中间停止管道,同时避免到达外部 catchError 和管道中的下一个运算符?

您可以 return 空 Observable 以防止事件或错误到达将要被销毁的组件:

return this.httpClient
  .request('POST', "token", { observe: 'response' })
  .pipe(
    map(response => {
      // some logic when the token was refreshed successfully
    }),
    catchError(err => {
      this.routingService.navigateToLoginNoQuery();
      return EMPTY;
    })
  );

如果我理解正确,那么 takeUntil 接线员也许可以帮助您。 例子看起来像这样:

export class MyHttpInterceptor implements HttpInterceptor {
  anyError = new Subject();

  intercept(req: HttpRequest, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(req)
      .pipe(
         takeUntil(this.anyError),
         catchError(err => {
             this.anyError.next();
             ...
         }
      )
  }
}