rxjs throwError

时间:2019-02-28 21:38:34

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

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

方法:从同一工作区中的lib项目提供自定义ErrorHandler。这是我的库结构:

@common/error-handling lib

我有以下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错误响应。服务我的应用程序时,控制台中会显示以下内容:

Error shown in console, but not catched by global error handler

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

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

return throwError(error);

http-error.interceptor.ts中的

没有到达我的全局错误处理程序。

这与zone.js相关吗?该错误被抛出,并没有冒泡到应用程序的其余部分。我对zone.js不太熟悉。

还有其他想法吗?

谢谢!

最好, 最多

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

如果您的可观察对象对错误进行了回调,则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);
  // },
);
}