如何在本地处理错误并跳过 Angular HTTP 拦截器?

Sal*_*ene 6 angular

我有一个 AngularHttpInterceptor来捕获错误并根据状态代码显示适当但通用的错误消息。

我有一个特定的情况,我实际上期望和错误消息(UI 尝试释放刚刚删除的资源上的锁定,所以我得到 404)。

在这种情况下,我想直接在调用 API 的地方处理错误,并跳过拦截器。

我试过这个:

releaseReviewerLock(itemType: EquipmentItemType, itemId: EquipmentItem["id"]): Observable<void> {
  return this.http
    .post<void>(`${this.configUrl}/${itemType.toLowerCase()}/${itemId}/release-reviewer-lock/`, {})
    .pipe(
      catchError(e => {
        if (e.status === HttpStatusCode.NotFound) {
          // We can ignore the 404 because the item has just been deleted, so there's nothing to release.
          return EMPTY;
        }
      })
    );
}
Run Code Online (Sandbox Code Playgroud)

但无论如何,不​​仅我的拦截器被调用,catchError上面的块根本没有执行(断点没有停止)。

我可以在不修改拦截器并保持单一职责的情况下实现我想要的吗?

谢谢!

Thi*_*lvo 6

我们可以传递一些元数据上下文HttpClient然后在HttpInterceptor.

当然,这意味着要在内部添加一些逻辑HttpInterceptor,但是由于元数据上下文,该代码可以更加通用,并且保持简单。

例如:

api.service.ts

this.httpClient
  .get('http://...', {
    context: new HttpContext().set(IGNORED_STATUSES, [404]),
  })
  .pipe(
    catchError((e) => {
      console.log('Error catched locally', e);
      return of(EMPTY);
    })
  )
  .subscribe();
Run Code Online (Sandbox Code Playgroud)

error.interceptor.ts

export const IGNORED_STATUSES = new HttpContextToken<number[]>(() => []);

export class CustomHttpInterceptor implements HttpInterceptor {
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const ignoredStatuses = req.context.get(IGNORED_STATUSES);

    return next.handle(req).pipe(
      catchError((e: HttpErrorResponse) => {

        // if ignored statuses are set
        // and returned status matched 
        if (ignoredStatuses?.includes(e.status)) {
          // rethrow error to be catched locally
          return throwError(() => e);
        }

        // process error...
        console.log('error interceptor !!', e);
        return of();
      })
    );
  }
}

Run Code Online (Sandbox Code Playgroud)