Angular error handling and logging - Call GlobalErrorHandler's handleError

◇◆丶佛笑我妖孽 提交于 2021-02-08 10:50:56

问题


I'm following an Angular error handling/logging tutorial here: https://www.code-sample.com/2017/09/angular-4-error-handling-and-logging.html

My question is - how can I call the handleError method (residing in the global-error-handler.service.ts file, seen in step 3 below) from one of my services?

In my ErrorLogService, I'm also instantiating a POST request (with data coming from a component) and using catchError to try and call handleError from global-error-handler.service.ts, but I'm getting [ts] Property 'handleError' does not exist on type 'typeof GlobalErrorHandler'.:

ErrorLogService:

  postData(body):Observable<any>{

    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json'
      }),
      withCredentials: true
    }
    return this.http.post(this.baseUrl2, body, httpOptions)
    .pipe(
      catchError(GlobalErrorHandler.handleError)
    )
  }


Step 1 - Create an AppConstants class (AppConstants.ts) for global error messages:

export class AppConstants {
public static get baseURL(): string { return 'http://localhost:4200/api'; }
public static get httpError(): string { return 'There was an HTTP error.'; }
public static get typeError(): string { return 'There was a Type error.'; }
public static get generalError(): string { return 'There was a general error.'; }
public static get somethingHappened(): string { return 'Nobody threw an Error but something happened!'; }
}

Step 2 – Create an error log service (ErrorLogService) for error logging:

import { Injectable} from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import{ AppConstants} from '../app/constants'
// my import of globalErrorHandler, so I can (hopefully) use its handleError method
import { GlobalErrorHandler } from '../global-error-handler/global-error-handler';

//#region Handle Errors Service
@Injectable()
export class ErrorLogService {

  constructor() {  }

  //Log error method
  logError(error: any) {
    //Returns a date converted to a string using Universal Coordinated Time (UTC).
    const date = new Date().toUTCString();

    if (error instanceof HttpErrorResponse) {
      //The response body may contain clues as to what went wrong,
      console.error(date, AppConstants.httpError, error.message, 'Status code:',
                                                  (<HttpErrorResponse>error).status);
    }
    else if (error instanceof TypeError) {
      console.error(date, AppConstants.typeError, error.message, error.stack);
    }
    else if (error instanceof Error) {
      console.error(date, AppConstants.generalError, error.message, error.stack);
    }
    else if(error instanceof ErrorEvent){
      //A client-side or network error occurred. Handle it accordingly.
      console.error(date, AppConstants.generalError, error.message);
    }
    else {
      console.error(date, AppConstants.somethingHappened, error.message, error.stack);
    }
  }
}
//#endregion

Step 3 - Create a global error handler service (GlobalErrorHandler.service.ts) for using the error log service to log errors

import { Injectable, ErrorHandler } from '@angular/core';
import {ErrorLogService} from './error-log.service';

// Global error handler for logging errors
@Injectable()
export class GlobalErrorHandler extends ErrorHandler {
    constructor(private errorLogService: ErrorLogService) {
       //Angular provides a hook for centralized exception handling.
       //constructor ErrorHandler(): ErrorHandler
        super();
    }

    handleError(error) : void {
        this.errorLogService.logError(error);
    }
}

Step 4 – In app.module.ts, import services, global handler and error handler:

import { NgModule, ErrorHandler } from '@angular/core';
import {ErrorLogService} from './error-logg.service';
import {GlobalErrorHandler} from './global-error.service';

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    UserComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    RouterModule.forRoot([
      { path: '', component: AppComponent, pathMatch: 'full', canActivate: [AuthGuard]},
      { path: 'user', component: UserComponent, canActivate: [AuthGuard]},
      { path: 'login', component: LoginComponent}])
  ],
  providers: [ ErrorLogService, // register global error log service
              GlobalErrorHandler,// register global error handler
              EmployeeService, // register Employee service
              ValidationService, //register Validation Service
              AuthenticationService, //register Authentication Service
              UserService],//register User Service
  bootstrap: [AppComponent]
})
export class AppModule { }

回答1:


I got it! I ended up using another tutorial where they instantiate the GlobalErrorHandlerService differently within App.Module.ts. Following this worked (a beautiful error handling tutorial): https://www.concretepage.com/angular/angular-custom-error-handler

In it, within app.module.ts they did the following (note the providers array):

@NgModule({
  ------
  providers: [
    GlobalErrorHandlerService,
    { provide: ErrorHandler, useClass: GlobalErrorHandlerService },
    -----    
  ]
})
export class AppModule { } 

Also, in my case I should never have been trying to call handleError. GlobalErrorHandlerService overrides the default ErrorHandler. Thus, the new handleError method created in my 'GlobalErrorHandlerService' will have errors thrown to it automatically or by using the 'throw' keyword (on observables that you're .subscribed to).

Please take a good look at the above tutorial if you're having trouble with Angular Global Error Handling.



来源:https://stackoverflow.com/questions/51618921/angular-error-handling-and-logging-call-globalerrorhandlers-handleerror

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!