Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 doesn't update view after exception is thrown

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?

like image 725
Bernard Ng Avatar asked Jun 15 '16 12:06

Bernard Ng


People also ask

Does throw exception stop execution JavaScript?

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.

How do you handle exceptions in Angular?

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) .

Can we use try catch in Angular?

The good news is, Angular has a kind of global try/catch that we can use in one centralized location to catch all exceptions.

How to throw new exception in JavaScript?

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');


2 Answers

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 EventEmitters 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

like image 109
yurzui Avatar answered Nov 16 '22 02:11

yurzui


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

like image 38
Andrei Zhytkevich Avatar answered Nov 16 '22 01:11

Andrei Zhytkevich