rxjs处理错误与拦截器不兼容

问题描述:

基于此问题角度拦截HTTP错误,该问题已解决,我正面临

Based on this question Angular intercepting http errors that is resolved, I'm facing a huge philosophical issue.

我所有的服务都像这样:

All my services look like this:

public getSomething(): Observable<Something> {
    return this.http
        .get<Something>(url)
        .pipe(
            map(res => res.data),
            catchError((e): Observable<any> => of(e))
        );
}

如果我的身份验证令牌无效/已过期,则服务会捕获该错误。
我可以在那儿打电话注销。

If my authentication token is invalid / expired, the service catches the error. I can call log out right there.

但是,如果我有很多服务,则必须重复此过程很多次。因此,我需要配置拦截器或自定义错误处理程序。

However, if I have a lot of services, I have to repeat this process that many times. Thus I need to configure an interceptor or a custom error handler.

如果我将catchError保留在服务中,则两者均不会触发。

Both are not triggered if I keep catchError in the services.

如果我选择保留DRY,则需要删除catchError。如果我删除catchError,rxjs几乎变得无用(完成,重试等)。

If I choose to stay DRY, I need to remove catchError. If I remove catchError, rxjs becomes practically useless (finalize, retry...etc.)

如果我选择保留catchError,则需要修改所有这些以调用某种全局错误处理功能可以保持一定的干燥状态。但是然后我没有像应该那样使用Angular。

If I choose to keep catchError, I need to modify all of them to call some kind of global error handling function to stay somewhat DRY. But then I'm not using Angular like I should.

如何处理这种情况?

编辑: https://stackblitz.com/edit/angular-m2jc9n

有一个错误处理程序处于活动状态,拦截器在app.module中被注释。
如果从服务中删除catchError,则会触发ErrorHandler,否则catchError优先。

There's the ErrorHandler active, the Interceptor is commented in app.module. If you remove catchError from the service, the ErrorHandler is triggered, otherwise catchError takes precedence.

如果需要要使用共享的拦截器,您可以使用 HTTP_INTERCEPTOR

If you want to have a shared interceptor, you have in angular the HTTP_INTERCEPTOR:

在您的 module.ts

@NgModule({
  declarations: [
   ...
  ],
  imports: [
   ...
  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: LoginInterceptor,
      multi: true
    }
  ]
})

服务 LoginInterceptor

@Injectable()
export class LoginInterceptor implements HttpInterceptor {

  constructor() {
  }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    return next.handle(request).pipe(
      tap(() => {
        }, (err: any) => {
          if (err instanceof HttpErrorResponse) {
            // DO here what you want
            // this.router.navigate(['login']);
          }
        }
      )
    );
  }
}

替代是在路线顶部使用后卫