Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Service in Angular Custom ErrorHandler

I have implemented the following ErrorHandler in my project:

export class RavenErrorHandler implements ErrorHandler {
  handleError(err: any): void {
    Raven.captureException(err.originalError);
  }
}

I also provided it correctly in my AppModule. But I also want to use an AlertService and a Router to route the user to a generic error page after I log the error remotely as is done above.

How do I go about in injecting those services to the custom ErrorHandler?

If I just inject them into the constructor, the app never loads (stuck at Loading...) and nothing is displayed on the console at all!

UPDATE: I added @Injectable to RavenErrorHandler above, and now I'm getting the following error:

[Error] Unhandled Promise rejection: (8) "Provider parse errors: Cannot instantiate cyclic dependency! ApplicationRef (\"[ERROR ->]\"): in NgModule AppModule in ./AppModule@-1:-1" "; Zone:" "
<root>" "; Task:" "Promise.then" "; Value:" Error: Provider parse errors: Cannot instantiate cyclic dependency! ApplicationRef ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1 — compiler.es5.js:10921 parse — compiler.es5.js:10921 compile — compiler.es5.js:17394
  _compileModule — compiler.es5.js:25652 run — zone.js:141 (anonymous function) — zone.js:805 runTask — zone.js:181 drainMicroTaskQueue — zone.js:574 promiseReactionJob (anonymous function) (vendor.bundle.js:98814) onUnhandledError (polyfills.bundle.js:2613)
  handleUnhandledRejection (polyfills.bundle.js:2637) _loop_1 (polyfills.bundle.js:2628) microtaskDrainDone (polyfills.bundle.js:2632) drainMicroTaskQueue (polyfills.bundle.js:2565) promiseReactionJob [Error] Error: Uncaught (in promise): Error: Provider
  parse errors: Cannot instantiate cyclic dependency! ApplicationRef ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1 parse@http://localhost:4200/vendor.bundle.js:64024:28 compile@http://localhost:4200/vendor.bundle.js:70497:29 _compileModule@http://localhost:4200/vendor.bundle.js:78755:80
  run@http://localhost:4200/polyfills.bundle.js:2124:49 http://localhost:4200/polyfills.bundle.js:2788:60 runTask@http://localhost:4200/polyfills.bundle.js:2164:57 drainMicroTaskQueue@http://localhost:4200/polyfills.bundle.js:2557:42 promiseReactionJob@[native
  code] — zone.js:757 (anonymous function) (vendor.bundle.js:98814) onUnhandledError (polyfills.bundle.js:2615) handleUnhandledRejection (polyfills.bundle.js:2637) _loop_1 (polyfills.bundle.js:2628) microtaskDrainDone (polyfills.bundle.js:2632) drainMicroTaskQueue
  (polyfills.bundle.js:2565) promiseReactionJob
like image 862
Sammy Avatar asked Oct 29 '25 01:10

Sammy


1 Answers

You can't inject Router directly but you can use injector and get Router instance within handlerError methos.

Don't forget to add @Injectable() decorator to your custom handler

@Injectable()
export class MyErrorHandler extends ErrorHandler {
  constructor(private service: TestService, private zone: NgZone, private inj: Injector) {
    super();
  }

  handleError(err) {
    let router = this.inj.get(Router);
    debugger;
  }
}

Test it here

Don't read below :) It's internally logic

So my module factory, that is generated from our code, will look like:

AppModuleInjector.prototype.createInternal = function() {
  var self = this;
  self._CommonModule_0 = new jit_CommonModule27();
  self._TestService_1 = new jit_TestService28();
  self._ErrorHandler_2 = new jit_MyErrorHandler29(self._TestService_1,self.parent.get(jit_NgZone16),self);
like image 164
yurzui Avatar answered Oct 30 '25 18:10

yurzui