When an exception is caught by Angular 2's exception handler, the UI no longer 'updates'.
I have a very simple example here:
import { Component, ExceptionHandler, Injectable, OnInit, provide } from '@angular/core';
import { bootstrap } from '@angular/platform-browser-dynamic';
import { Subject } from 'rxjs/Subject'
export interface Alert {
message: string;
}
@Component({
selector: 'my-app',
template : `
<h3>Parent</h3>
{{aValue}}
<br/>
<br/>
<button (click)='doIt()'>do it</button>
<br/>
<br/>
<button (click)='breakIt()'>break it</button>
`
})
export class App implements OnInit {
private aValue: boolean = true
constructor() { }
alerts: Alert[] = [];
doIt(){
console.log('Doing It')
this.aValue = !this.aValue
}
breakIt(){
console.log('Breaking It')
throw new Error('some error')
}
}
bootstrap(App).catch(err => console.error(err));
The Do It button flips the boolean
which is reflected in the interpolated value in the template. However, once the Break It
button is pressed (which cases an error to be thrown), the interpolated value no longer updates when the 'Do it' button is hit. However, the console still logs the messages Doing it
.
The problem I'm dealing with is I would like to create a custom exception handler that warns the user and possibly does some work to clear a form when something has gone wrong, but what I'm seeing is if I throw an error on a button click to test it, all UI updates stop. However, buttons continue to function, meaning any buttons that post requests will do so if the form is in a good state. The UI however has ceased to update and inform the user what is happening.
I'm not sure if this is a problem with Zones or something else, but attempting an NgZone.run()
didn't seem to solve the problem for me. If an error is meant to break a component's UI, what's the correct approach to my problem?
The throw statement throws a user-defined exception. Execution of the current function will stop (the statements after throw won't be executed), and control will be passed to the first catch block in the call stack. If no catch block exists among caller functions, the program will terminate.
The default Error handling in Angular is handled by Errorhandler class, which is part of the @angular/core module. This is global error handler class which catches all exception occurring in the App. This class has a method handleError(error) .
The good news is, Angular has a kind of global try/catch that we can use in one centralized location to catch all exceptions.
create(Error. prototype); With a custom exception object created, all we have to do is throw it like any other error: throw new CustomException('Exception message');
Since angular 4.1.1 (2017-05-04) https://github.com/angular/angular/commit/07cef36
fix(core): don’t stop change detection because of errors
- prevents unsubscribing from the zone on error
- prevents unsubscribing from directive
EventEmitter
s on error- prevents detaching views in dev mode if there on error
- ensures that
ngOnInit
is only called 1x (also in prod mode)
it should work without additional code
@Component({
selector: 'my-app',
template : `
{{aValue}}
<button (click)='doIt()'>do it</button>
<button (click)='breakIt()'>break it</button>
`
})
export class App implements OnInit {
private aValue: boolean = true
doIt(){
console.log('Doing It')
this.aValue = !this.aValue
}
breakIt(){
console.log('Breaking It')
throw new Error('some error')
}
}
Plunker Example
Don't rely on code execution after an unhandled Exception
happened.
You have to handle the exception in the place where you expect it to happen.
Error handling: http://www.javascriptkit.com/javatutors/trycatch.shtml
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With