Exception not bubbling up to global Ionic error handler

#1

Hello Ionic community!
I am subscribing to an observable and throwing an exception in it’s error handler function. I want to handle this exception in the global Ionic error handler.

this.itemsService.stageItems([stagedItem]).subscribe(
    (result: any) => {
            . . .
    }, error => {
            console.log(`getting error from stageItems call`);
            throw new Error(error); // <- this thrown exception won't bubble up to the global error handler!
});

I replaced the default Ionic error handler:

@Injectable()
export class MfpErrorHandler extends IonicErrorHandler implements ErrorHandler {
    constructor(private injector: Injector) {
        super();
    }

    handleError(error: any): void {
        . . .
    }
}

app.module.ts:

@NgModule({
    . . .
    providers: [
        . . . ,
        {provide: ErrorHandler, useClass: MfpErrorHandler}
    ]
})

The custom error handler method handleError() is successfully called for other exceptions, but not for the thrown exception as described above. Instead I receive an error message:

Error in Error callbackId: somePlugin1267305069 : Error: [object Object]
Uncaught Error: [object Object]
_ at SafeSubscriber.error (item-stager.ts:70)
_ at SafeSubscriber.tryOrUnsub (Subscriber.js:242)
_ at SafeSubscriber.error (Subscriber.js:201)

_ at Subscriber.error (Subscriber.js:132)
_ at Subscriber.error (Subscriber.js:106)_
_ at SafeSubscriber.error (items.ts:49)
_ at SafeSubscriber.tryOrUnsub (Subscriber.js:242)
_ at SafeSubscriber.error (Subscriber.js:201)

_ at Subscriber.error (Subscriber.js:132)
_ at Subscriber.error (Subscriber.js:106)_

What am I doing wrong here? Thanks for your advice!

1 Like
#2

As a workaround, instead of raising an exception I call the ErrorHandler directly. That works, but it’s not really a clean solution.

constructor(private errorHandler: MfpErrorHandler) { ... }

this.itemsService.stageItems([stagedItem]).subscribe(
    (result: any) => {
            . . .
    }, error => {
            this.errorHandler.handleError(error); // <- calls the error handler by reference
});

However I am still interested in a real solution.

#3

Ionic v3 right?

Not sure that’s the issue, I just noticed that I’m not declaring my error handler the same way as you do respectively I don’t mark it as Injectable, don’t know if that could help?

You do

@Injectable()
export class MfpErrorHandler extends IonicErrorHandler implements ErrorHandler {
    constructor(private injector: Injector) {
        super();
    }

    handleError(error: any): void {
        . . .
    }
}

I do

export class MyErrorHandler extends IonicErrorHandler {

    handleError(err:any) : void {
        super.handleError(err);
        // stuffs
    }
}
#4

Thanks reedrichards for your feedback!

If I don’t mark as Injectable I am getting an exception directly on app startup (which is due to the fact that I am using an Injector/@angular/core in this handler):

vendor.js:104604 Uncaught Error: Can't resolve all parameters for MfpErrorHandler: (?).
    at syntaxError (vendor.js:89101)
    at CompileMetadataResolver._getDependenciesMetadata (vendor.js:104321)
    at CompileMetadataResolver._getTypeMetadata (vendor.js:104156)
    at CompileMetadataResolver._getInjectableMetadata (vendor.js:104136)
    at CompileMetadataResolver.getProviderMetadata (vendor.js:104496)
    at vendor.js:104407
    at Array.forEach (<anonymous>)
    at CompileMetadataResolver._getProvidersMetadata (vendor.js:104367)
    at CompileMetadataResolver.getNgModuleMetadata (vendor.js:103935)
    at JitCompiler._loadModules (vendor.js:123028)

When removing Injectable mark and Injector from the code I am now facing another error message when throwing an exception:

Unhandled Promise rejection: ...

Maybe it’s a step futher?

I am using Ionic v4.0.0
Thanks!

#5

Ohhhhhhh then for Ionic v4 there isn’t any IonicErrorHandler anymore I think

My error handler for v4 looks like the following:

export class MyErrorHandler extends ErrorHandler {

   handleError(err: any): void {
      super.handleError(err);
      // do stuffs
  }
}