2

I have a custom exception handler like this in which I'm trying to inject a service (ErrorReportingService)

import { ExceptionHandler, Injectable } from '@angular/core';
import {ErrorReportingService  } from '../services/ErrorReportingService';

@Injectable()
export class InsightsExceptionHandler extends ExceptionHandler {
    constructor(private _errorReporter: ErrorReportingService) {
        super(null, null);
    }

call(error, stackTrace = null, reason = null) {
    this._errorReporter.logError(error);

    }
}

The service I'm trying to inject looks like this

import { Http, Response } from '@angular/http';
import { Injectable, Inject } from '@angular/core';

@Injectable()
export class ErrorReportingService {
    private ErrorReportingUrl = `/property/insights/api/errorreporting`;
    constructor(private _http: Http) { }

    logError(error: any) {
        var body = JSON.stringify(error);
        this._http.post(this.ErrorReportingUrl, body, null);
    }
}

The ErrorReportingService is registered under providers of the app component.

I have also tried injecting the service differently like this:

export class InsightsExceptionHandler extends ExceptionHandler {
    private _errorReporter: ErrorReportingService;
    constructor( @Inject(ErrorReportingService) errorReporter: ErrorReportingService) {
        super(null, null);
        this._errorReporter = errorReporter;
    }
......

I get this error when trying to run the app:

Error: (SystemJS) EXCEPTION: Error during instantiation of ApplicationRef_! (ApplicationRef -> ApplicationRef_).
ORIGINAL EXCEPTION: No provider for ErrorReportingService! (ExceptionHandler -> ErrorReportingService)
ORIGINAL STACKTRACE:
Error: DI Exception
Toby Holland
  • 1,029
  • 2
  • 14
  • 29

2 Answers2

3

I guess in your application main file where you are bootstrapping your application, you must be using something similar to below for Exception handling,

Add all the services you need in the bootstrap provider itself,

bootstrap(
<YourAppComponent>,
[
    // inject all the services which you need here 
    // so that they can be injected wherever required

    ErrorReportingService,
    provide(ExceptionHandler, {
        useClass: InsightsExceptionHandler 
    })
]).catch(err => console.error(err));
Madhu Ranjan
  • 17,334
  • 7
  • 60
  • 69
  • Thank you, this worked. Although I don;t understand why I have to provide them in the bootstrap call as they are already in the providers of the App component? – Toby Holland Aug 03 '16 at 05:44
  • 1
    We are overriding default Angular ExceptionHandler by registering a provider for that in bootstrap, and Angular makes a decision when to create the service based upon where it is registered, so in this case at bootstrap, so it will search for all the dependency on the same level, although you may have added the ErrorReportingService provider in App Component that will create a new instance of ErrorReportingService for App component or children. Hope this helps!! – Madhu Ranjan Aug 03 '16 at 14:31
0

To break the cycle use

@Injectable()
export class ErrorReportingService {
  constructor(injector:Injector) {
    setTimeout(() {
      this.appRef = injector.get(ApplicationRef);
    });
  }
}

I don't know if this is exactly what causes the cycle because your question doesn't contain the ErrorReportingService source but you should get the idea.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567