Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to log all possible console errors occurring in Angular application on a client's side?

Currently, my Angular application consists of a significant number of submodules and components. Angular applications are quite sensitive to html rendering errors. For example, if we get a NULL object from an API and trying to get access to its property, it partially breaks rendering of the application.

It is quite difficult to handle and test such cases taking into account that the application is constantly growing. Do you know if it is possible to create a script that can log all error appearing in a console?

Here what I have got:

1) An http requests error handle to log broken requests from an API:

  private handleError<T> (operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {

      // TODO: send the error to remote logging infrastructure
      console.error(error); // log to console instead

      // TODO: better job of transforming error for user consumption
      this.log(`${operation} failed: ${error.message}`);

      // Let the app keep running by returning an empty result.
      return of(result as T);
    };
  }

2) Client-side logger but for whatever reason it only logs errors from crawlers :)

<script>
  window.onerror = function(m,u,l,c) {
    if (window.XMLHttpRequest) {
      var xhr = new XMLHttpRequest();
      var data = "msg="+encodeURIComponent(m)
        +"&url="+encodeURIComponent(u)
        +"&line="+l
        +"&col="+c
        +"&href="+encodeURIComponent(window.location.href);
      xhr.open("GET", "logger.php?"+data, true);
      xhr.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
      xhr.send();
    }
  };
</script>

It would be very useful to get a script that can simply log all errors from console and

like image 913
Denis Evseev Avatar asked Aug 04 '19 23:08

Denis Evseev


People also ask

How does Angular handle client side errors?

The simplest way to handle errors in Angular is to use Angular's HttpClient service along with RxJS operators throwError and catchError . Http request is made, and it returns the data with a response if anything wrong happens then it returns an error object with error status code.

How does Angular handle console errors?

One traditional way of handling errors in Angular is to provide an ErrorHandler class. This class can be extended to create your own global error handler. This is also a useful way to handle all errors that occur, but is mostly useful for tracking error logs.

What does console log do in Angular?

console. log is a JavaScript function that logs messages to the developer's console or the browser console to the web page. This method helps Angular developers by informing them about the errors, warnings, and what is happening during the execution of their code.

Who handles errors generated in Angular?

Global Error Handling in Angular is handled by the Errorhandler class which is part of the @angular/core module. This is a global error handler class which catches all exceptions thrown by the application. In this approach, we create a class that will be implemented by the ErrorHandler class.

Can we use console log in angular?

Logging in Angular Applications Programmers frequently use console.log to record errors or other informational messages in their Angular applications. Although this is fine while debugging your application, it's not a best practice for production applications.

How do I know if my angular application is failing?

You should see this: An error in an Angular application can either be a client-side error or server-side error: Client-side error: errors related to front-end code and the network — they throw 4xx status codes. Server-side error: errors related to back-end codes, database, and file system. They usually throw 5xx status codes.

How to log angular errors effectively?

Luckily, you can effectively log Angular errors by just integrating your application with Loupe Server. Loupe Server is a centralized logging platform with real-time log monitoring and a client-side logging agent designed explicitly for Angular applications. You can learn more about Loupe Server here, or try our free trial in the link below.

How does AngularJS handle client-side errors?

AngularJS has pretty good error handling and, within its context, will catch client-side errors and log them to the console allowing your application to continue. The problem, as outlined at the beginning of this article, is that the only person who knows the error occurred is the user sitting in front of the screen. So let’s fix this.


Video Answer


2 Answers

If you wish to catch and log all the errors (not only HTTP nature ones) in your Angular application I'd propose you the way that Sentry and other bug trackers use.

Angular has an ErrorHandler class which provides a hook for centralized exception handling.

So your task would be to create your own error handler. I usually do it like this:

import {ErrorHandler, Injectable} from '@angular/core';
import {LoggerService} from './some/logger.service';

@Injectable()
export class CustomErrorHandlerService extends ErrorHandler {

    constructor(private logger: LoggerService) {
        super();
    }

    handleError(error) {
        // Here you can provide whatever logging you want
        this.logger.logError(error);
        super.handleError(error);
    }
}

The next step is to use your error handler by means of Dependency Injection. Just add it in your AppModule like this:

import {CustomErrorHandlerService} from '~/app/_services/custom-error-handler.service';

@NgModule({
    imports: [...],
    declarations: [...],
    providers: [
        ...
        {provide: ErrorHandler, useClass: CustomErrorHandlerService},
    ],
    bootstrap: [AppComponent]
})

That's it. The key feature of such implementation is that this service handles all possible errors, appearing in your application (just like you ask in your question) including HTTP errors and others.

Please, leave your comments if you have any additional questions.

like image 120
Sergey Mell Avatar answered Oct 12 '22 20:10

Sergey Mell


When I started working with Angular, I found this article helpful: Angular: Adding Logging in Angular Applications.

If you follow the guidance, you end up with a LoggingService that you can configure to log errors to one of three (or all) locations:

  • The console
  • Local Storage
  • A Database (via POST request)

What the article leaves out is how to catch the errors automatically. You can do this with an HttpInterceptor. Here's an example from an application I'm working on:

http-request-interceptor.ts

import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpRequest, HttpErrorResponse, HttpInterceptor } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';
import { Router } from '@angular/router';

import { LogService } from '../services/log.service';

@Injectable()
export class HttpRequestInterceptor implements HttpInterceptor {
  constructor (private logService: LogService, private router: Router) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const newReq = req.clone({
      headers: req.headers.set('Content-Type', 'application/json'),
      withCredentials: true
    });
    return next.handle(newReq)
      .pipe(
        retry(1),
        catchError((error: HttpErrorResponse) => {
          let displayError = '';
          let serverError = '';
          let clientError = '';

          if (error.error instanceof ErrorEvent) {
            // client-side error
            clientError = `Error: ${error.error.message}`;
            this.logService.error(clientError);
          } else {
            // server-side error
            displayError = error.error;
            serverError = `Error Code: ${error.status}\n${error.message}\n${error.error}`;

            if (error.status === 401) {
              this.logService.error(serverError);
              this.router.navigate(['/unauthorized', { message: error.error}]);
            }

            if (error.status >= 500) {
              this.logService.error(serverError);
              this.router.navigate(['/error']);
            }
          }
          return throwError(displayError);
        })
     );
  }
}

HttpInterceptors are very powerful. This one does the following:

  1. Adds a Content-Type to the header of every request, setting it to application/json
  2. Sends each request with credentials
  3. Retries each request a second time before error handling
  4. Handles errors
    • When the User is Unauthorized, it redirects to a custom 401 error page
    • When the Server throws an Error (500+), it redirects to a custom server error page
    • In all cases, it logs the error using the logging service mentioned above
    • It also throws the error back to the caller, so if your API returns user-friendly error messages you can catch them in your controller and show them to your users

To register an HttpInterceptor in your application you need a module:

http-interceptor.module.ts

import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpRequestInterceptor } from './http-request-interceptor';


@NgModule({
  providers: [
    { provide: HTTP_INTERCEPTORS,
      useClass: HttpRequestInterceptor,
      multi: true
    }
  ]
})

export class HttpInterceptorModule { }

Then you register this module in your app.module.ts file and include it in the imports array.

like image 26
Danya Smith Avatar answered Oct 12 '22 20:10

Danya Smith