Capture all JavaScript errors in Angular2

4

As the title says, I'm needing to capture all the errors generated in JavaScript but by angular.

The idea is to raise a service that sends the errors that will happen on the client's side to have a log of errors in the server, to later correct them.

If it was JavaScript, only things like

would work
window.onerror = MyErrorHandler()

In angle there is a class ErrorHandler that can be extended but only captures the errors that are generated in angular.

I need to capture everyone no matter how insignificant.

    
asked by Ricardo D. Quiroga 07.04.2017 в 15:49
source

1 answer

6

With Angular 2 , Typescript was introduced as the most suitable language to write an application with angle 2. If so, one can practically eliminate the most trivial errors of javascript activating the Ahead of Time compilation .

If you are using @ angular / cli this is done through the aot = true

$> ng build --aot=true
  

By activating this feature, we discard errors such as incorrect data links in the views, or use of non-compatible data such as trying to link an event to an object and not a function.

For example:

import {Http} from '@angular/http';
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app works!';

  constructor(private http:Http){    
  }

  errorFunc = 34;

}

And in the view of our component:

<h1>
  {{title}}
</h1>
<p>
 <button (click)="errorFunc()" >Please dont touch me</button>
</p>

If we compile our application in the traditional way (aot = false) we do not receive any error until we use the button of our application, but if we compile with the compilation Ahead of Time we will obtain the following:

For most errors

You can use the class ErrorHandler of @angular/core to handle almost any error that arises during the execution of our angular application 2 overwriting the method handleError(error:Error):void . It's worth mentioning that I use this class just to send client-side errors to a server (Raygun) :)

For example, to show errors as notifications:

import { Injectable, ErrorHandler  } from '@angular/core';
import {NotificationsService, SimpleNotificationsComponent} from 'angular2-notifications';

@Injectable()
export class MyAppErrorHandler extends ErrorHandler {

  constructor(private _toastService: NotificationsService,){
    super(false);    
  }

  public handleError(error: Error):void
  {    
    //do somethign with the error    
    //for example show a toast
    this._toastService.error("Error","An error has ocurred");      
  };
}

And finally you register it at the level of your application:

import { AppComponent } from './app.component';
import { MyAppErrorHandler } from './error-handling';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [       
    ],
    providers: [         
        { provide: ErrorHandler, useClass: MyAppErrorHandler }      
    ],
    bootstrap: [AppComponent]
})
export class AppModule { } 

Reference: link

If you want to go further

We can hack Zone.js to capture the errors that happen when running in that context by entering the following fragment in the index.html of our application.

<script>

  Zone.current._zoneDelegate.handleError = function () {
      console.log("Error handled by ZoneJS :: " + arguments);
  };

</script>

  

It is important to highlight the undocumentedness of this process and the suceptible to the change in case Zone.js change the way it works in addition to the fact of not being able to use Angular 2 classes in this context.

Reference: link

    
answered by 07.04.2017 / 16:25
source