2

I'm working on a angular application, the problem is when I want to debug it on some smart TVs there is no debug mode and in the background I have some errors that cause application to crash, so, is there any way to get all error messages and print it in a part of the page in my application?

Actually I want to have some kind of virtual console in my own application.

Thank you so much

Masoud Motallebipour
  • 414
  • 3
  • 16
  • 33
  • What you are trying to convey is called `logging` Search how you can log messages in Angular – ashwani Sep 24 '19 at 08:23
  • 2
    you will need to replace your console logs by a method of your choice located in a service. How to display them in your application is up to you. You may use a fixed floating panel or snackbar messages. I recommend that you use some kind of service to centralize your logs and make them accessible from everywhere in your app. – Zacharie Ménétrier Sep 24 '19 at 08:28
  • Possible duplicate of [Javascript: console.log to html](https://stackoverflow.com/questions/20256760/javascript-console-log-to-html) – karoluS Sep 24 '19 at 08:34

2 Answers2

3

There are several ways to debug it:

  • Console.log() - this outputs your message to console. Not sure if you can see it on tv though.
  • Create a global error handler, as provided in Angular documentation

If above does not work, you can try to use this solution, which I also found out somewhere on the internet a while ago by using a snackbar component, which displays errors as a popup:

error.service.ts:

import { Injectable } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';

@Injectable({
    providedIn: 'root'
})
export class ErrorService {

    checkOnline()
    {
        if (!navigator.onLine) {
            return 'No Internet Connection';
        }
    }

    getClientMessage(error: Error): string {
        return error.message ? error.message : error.toString();
    }

    getClientStack(error: Error): string {
        return error.stack;
    }

    getServerMessage(error: HttpErrorResponse): string {
        var msg = error.error.Message;
        if (!!msg)
            return msg + " : " + error.error.ExceptionMessage;
        return "Application can not execute because API hasn\'t been started";
    }

    getServerStack(error: HttpErrorResponse): string {
        return error.error.StackTrace;
    }
}

global-error-handler-component.ts:

import { ErrorHandler, Injectable, Injector } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { ErrorService } from './services/error.service';
import { MatSnackBar } from '@angular/material';

@Injectable()
export class GlobalErrorHandler implements ErrorHandler
{
    constructor(private injector: Injector, public snackBar: MatSnackBar) { }

    handleError(error: Error | HttpErrorResponse)
    {
        const errorService = this.injector.get(ErrorService);
        let message;
        let stackTrace = errorService.getClientStack(error);

        if (error instanceof HttpErrorResponse) // Server Error
            message = errorService.getServerMessage(error);
        else // Client Error
            message = errorService.getClientMessage(error);

        this.snackBar.open(message, 'X', { panelClass: ['error'] });
    }
}

app.module.ts:

import { GlobalErrorHandler } from './global-error-handler.component';
import { MatSnackBarModule } from '@angular/material/snack-bar';
...
  imports: [
...
    MatSnackBarModule,
...
  ],
  providers: [
...
    { provide: ErrorHandler, useClass: GlobalErrorHandler },
...
donatasj87
  • 760
  • 9
  • 23
2

you can override console.error method and create smoething like spy

@Injectable({
    providedIn:'root'
})
export class ConsoleSpyService {
  private errorStack :any[] = []
  constructor() { 
    const errMethod = console.error;

    console.error= (...args) => { 
      this.errorStack.push(args);

      errMethod(``,...args)
    }

    Object.freeze(console)
  }


  get errorList() {
    return this.errorStack;//.slice(0);
  }
}

you need to inject this class so it created

export class AppModule {

  constructor(c:ConsoleSpyService){}

 }

inject the service in component

  constructor(private conSpyServ:ConsoleSpyService) {

  }

  get errors(){
    return this.conSpyServ.errorList;
  }

template (disply errors list)

<div class="errors" *ngFor="let error of errors">
  {{error.join(' ')}}
</div>

you can display logging to console browser by comment this line errMethod(,...args) in ConsoleSpyService class

demo

Muhammed Albarmavi
  • 23,240
  • 8
  • 66
  • 91