【问题标题】:Custom global error handler not hit when http error response is re-thrown by rxjs throwError当 rxjs throwError 重新抛出 http 错误响应时,自定义全局错误处理程序未命中
【发布时间】:2020-12-13 12:16:26
【问题描述】:

目标:为服务器错误和应用程序错误(在 Typescript 代码中生成)提供一个全局错误处理程序。

如何:从同一工作空间内的 lib 项目中提供自定义 ErrorHandler。这是我的库结构:

我有以下 http-interceptor (http-error.interceptor.ts)

@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {

  constructor(@Inject(LOGGER_SERVICE) private logger: ILoggerService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(req)
    .pipe(
        catchError( (error: HttpErrorResponse) => {
          console.log('error');

          return throwError(error);
        })
    );
  }
}

以下自定义全局错误处理程序(errors-handler.ts):

import { ErrorHandler, Injectable } from '@angular/core';

@Injectable()
export class ErrorsHandler implements ErrorHandler {

    handleError(error: any): void {
        console.log('hi!');
    }

}

这是error-handling.module.ts

import { NgModule, ErrorHandler } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpErrorInterceptor } from './http-error.interceptor';
import { ErrorsHandler } from './errors-handler';

    @NgModule({
      declarations: [],
      imports: [
      ],
      exports: [],
      providers: [
        {provide: ErrorHandler, useClass: ErrorsHandler},
        {provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptor, multi: true}
      ]
    })
    export class ErrorHandlingModule { }

在我的 public_api.ts 文件中,我只导出模块

/*
 * Public API Surface of error-handling
 */

export * from './lib/error-handling.module';

在同一个工作区中,我有一个应用程序(Angular CLI 提供的默认应用程序,它不在项目文件夹中)。在我的 app.module.ts 中,我导入了 ErrorHandlingModule :

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';

import { ErrorHandlingModule } from '@common/error-handling';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { CoreModule } from './core/core.module';



@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    CoreModule,

    ErrorHandlingModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

我已经构建了我的@common/error-handling 库。 我还有一个带有 json-server 的假 api,我在其中定义了一个“类别”端点。我在 onInit 方法中调用 app.component.ts 上的该服务,通过调用端点“categorie”(不带“s”)产生 404 http 错误响应。当我提供我的应用程序时,控制台中有以下内容:

404 错误在那里,我也可以从 http-error.interceptor.ts 看到“错误”日志,但我看不到“嗨!”从我的自定义 ErrorHandler 中记录。

当我在调用假 api 端点后从 app.component.ts 抛出错误时,全局错误处理程序正在工作。不知何故,这条线

return throwError(error);

在 http-error.interceptor.ts 中没有到达我的全局错误处理程序。

它与 zone.js 相关吗?错误在那里被抛出,而不是冒泡到应用程序的其余部分。我对 zone.js 不是很熟悉。

还有其他想法吗?

提前致谢!

最好, 最大。

【问题讨论】:

  • 当我从 Interceptor ErrorHandler 抛出错误时,为什么无法捕获它?
  • @MuhammedOzdogan 我不明白你的问题。你能改一下吗?
  • 你有这个语句:“return throwError(error);”在 HttpErrorInterceptor 类中。 “ErrorsHandler”应该抓住它吗?

标签: angular typescript error-handling angular-http-interceptors zone.js


【解决方案1】:
export class ErrorHandlingModule { 
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: ErrorHandlingModule,
      providers: [
        {provide: ErrorHandler, useClass: ErrorsHandler},
        {provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptor, multi: true} ]
    };
}

然后在 AppModule 中导入 ErrorHandlingModule.forRoot()

更多信息 - https://angular.io/api/router/RouterModule#forRoot

【讨论】:

  • 感谢您的回答。这个问题真的很愚蠢。我有一个用作基础服务的类(从这个基础服务继承的所有服务),并且我有一个 catchError 来返回错误的默认值。由于这是链条的最后一个问题,我没有点击全局错误处理程序。很抱歉浪费您的时间,感谢您再次回答!
【解决方案2】:

如果你的 observable 对错误进行回调,throwError 运算符将返回给观察者,并且不会被全局错误拦截器拾取。

只需在 subscribe 中注释 catchError 块

getWorkData(id: string): void {
this.userDataService.getWorkData(id).subscribe(
  (response) => {
    this.Id = response.Id;
    this.localStorage.setItem('WorkData', response);
  }
  // (err) => {
  //   //this.monitoringService.logException(err);
  // },
);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-29
    • 2019-05-11
    • 2016-08-23
    • 1970-01-01
    • 2013-03-06
    • 1970-01-01
    • 1970-01-01
    • 2014-03-07
    相关资源
    最近更新 更多