0

I would like to have custom errors in my Angular2 app. Thus I have extended ErrorHandler in my component:

import { Component, ErrorHandler, OnInit } from '@angular/core';
import { GenericError } from './generic-error.component';

@Component({
    selector: 'custom-error-handler',
    templateUrl: 'app/error-handler/custom-error-handler.component.html?' + +new Date()
})

export class CustomErrorHandler extends ErrorHandler {
    errorText: string;

    constructor() {
        super(false);
    }

    ngOnInit() {
        this.errorText = 'Initial text!';
    }

    public handleError(error: any): void {
        if (error.originalError instanceof GenericError) {
            console.info('This is printed to console!');
            this.errorText = "I want it to print this in the template!";
        }
        else {
            super.handleError(error);
        }
    }
}

My template simply contains:

<span style="color:red">{{errorText}}</span>

First I see "Initial text!" in the template as set in ngOnInit. That's as expected.

I can then throw a new exception like this from a different component:

throw new GenericError();

and it hits the code with handleError and prints to console but it doesn't update my template errorText with:

"I want it to print this in the template!"

It's like it ignores my template, when inside the handleError function.

What could be the problem here?

* ADDED MORE INFORMATION *

I thought I should add some more information. So here is the module I made for CustomErrorHandler (maybe the problem is with the providers?):

import { NgModule, ErrorHandler } from '@angular/core';
import { CommonModule } from '@angular/common';

import { CustomErrorHandler } from './custom-error-handler.component';

@NgModule({
    declarations: [
        CustomErrorHandler
    ],
    imports: [
        CommonModule
    ],
    exports: [
        CustomErrorHandler
    ],
    providers: [
        { provide: ErrorHandler, useClass: CustomErrorHandler }
    ]
})
export class CustomErrorModule { }

There is indeed only one instance of the CustomErrorHandler (I checked with the Augury Chrome plugin).

For completeness, here is is the GenericError component:

export class GenericError {
    toString() {
        return "Here is a generic error message";
    }
}
15
  • Where are you including <custom-error-handler></custom-error-handler> ? Commented Apr 10, 2017 at 21:33
  • I include that in my app-component template. Commented Apr 10, 2017 at 21:36
  • 1
    It sounds like whatever component your throwing the error from is creating it's own instance of the component. Maybe try using a tool like Augury to inspect the scope hierarchy and make sure the component's a child of the one throwing the error. Or maybe this needs to be in a service so it's easier to share data between components. Hope this helps some. Commented Apr 10, 2017 at 23:16
  • 1
    You have one instance of service and one instance of component. Check constructors calling Commented Apr 12, 2017 at 7:02
  • 1
    Create two different classes. One for component and one for service. Then inject service in component. Commented Apr 12, 2017 at 7:04

1 Answer 1

0

The solution was to add a service as suggested in the question's comment track. This way I can set the property in the component and eventually show it in the template.

I created the service, so that it has a function which takes one parameter. Injected the service, call the service's function from the handleError in the component function, and send the text I want in the template as the parameter. Then I use an observable, to get the text back to the component.

In the constructor of the component, I added this observer.

let whatever = this.cs.nameChange.subscribe((value) => {
  setTimeout(() => this.errorText = value);
});

I needed to add the setTimeout, or else it would not update the template before the second time the observable was changed.

Phew! The Angular team should make this global exception handling easier in future releases.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.