ErrorHandler中的循环依赖

时间:2018-05-22 12:01:52

标签: angular

我创建了一个基本的错误处理程序,它应该捕获错误并通过烤面包机显示它们。

// global.errorHandler.ts
import { ErrorHandler, Injectable } from '@angular/core';
import { ToastrService } from 'ngx-toastr';

@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
  constructor( private toastr: ToastrService ) {}

  handleError( error ) {
    this.toastr.error( error.message );
    throw error;
  }
}

然后我将其导入app模块:

// app.module.ts
import { ErrorHandler, NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { GlobalErrorHandler } from './global.errorHandler';
import { ToastrModule } from 'ngx-toastr';

@NgModule({
  declarations: [ AppComponent ],
  imports: [ ToastrModule.forRoot() ],
  providers: [
    {
      provide: ErrorHandler,
      useClass: GlobalErrorHandler
    }
  ],
  bootstrap: [ AppComponent ]
})

export class AppModule {}

最后在AppComponent throw new Error( 'YOU DIDN\'T SAY THE MAGIC WORD' );

中抛出错误

在页面加载时,这会在控制台中记录错误:Cannot instantiate cyclic dependency!

我尝试使用Injector hack 解决方法,如下所示:

// global.errorHandler.ts
private toastr: ToastrService;
constructor( injector: Injector ) {
  setTimeout(() => {
    this.toastr = injector.get( ToastrService );
  });
}

这允许加载错误处理程序,但从不实际执行toast。我猜测它与Angular中加载依赖项的顺序有关,但我不知道如何解决这个问题。

2 个答案:

答案 0 :(得分:1)

从global.errorHandler.ts

中的handleError方法中删除throw错误
// global.errorHandler.ts
import { ErrorHandler, Injectable } from '@angular/core';
import { ToastrService } from 'ngx-toastr';

@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
  constructor( private toastr: ToastrService ) {}

  handleError( error ) {
    this.toastr.error( error.message );
    // throw error;  // Remove this line
  }
}

答案 1 :(得分:0)

另一种可能的解决方案是从注入器而不是构造函数注入获取 ToastrService,如下所述:

import { ErrorHandler, Inject, Injector, Injectable } from "@angular/core";
import { ToastrService } from "ngx-toastr";

@Injectable()
export class AppErrorHandler extends ErrorHandler {

  constructor(@Inject(Injector) private injector: Injector) { 
    super(true);
  }

  // Need to get ToastrService from injector rather than constructor injection to avoid cyclic dependency error
  private get toastrService(): ToastrService {
    return this.injector.get(ToastrService);
  }

  public handleError(error: any): void {
    this.toastrService.error(
      "An unexpected error has occurred.",
      "Error",
      {
        closeButton: true,
        timeOut: 5000,
        onActivateTick: true
      }
    );

    super.handleError(error);
  }
}

引用自:https://github.com/scttcper/ngx-toastr/issues/179#issuecomment-325724269