Error handler error error: Cannot read the "get" property from undefined (injector)

I create my own error handler in angular 4 to handle various application errors using the error hook

create a base class (app-error.ts) and other classes (for example, to handle 403 errors create an access-denied.ts class) that extend this base class.

the service was injected in the base class toastrService, and I want to display a custom message from the child class, but it gives an error on

Unable to read the 'get' property from undefined

thisissue belongs to the concept of OOPS. I do not understand how to override the parent method or call using my custom argument.

TS v 2.3.3 angular v 4.3.4

app.module.ts

providers: [
{ provide: ErrorHandler, useClass: AppErrorHandler }
]

. AppErrorHandler AppError, angular ErorHandler, .

import { Router } from '@angular/router';
import { Injectable, Injector } from '@angular/core';
import { HttpInterceptor, HttpResponse, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';

import {
    AuthFail,
    BadInput,
    NotFoundError,
    ServerError,
    AppError,
    AccessDenied,
} from '../shared/errors';
import { AuthenticationService } from './../authentication/authentication.service';


@Injectable()
export class ErrorInterceptor implements HttpInterceptor {

    private auth: AuthenticationService;
    constructor(private router: Router, private injector: Injector) { }
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const auth = this.injector.get(AuthenticationService);
        return next.handle(req).catch((err: HttpErrorResponse) => {
            if (err instanceof HttpErrorResponse) {
                if (err.status === 401) {
                    return Observable.throw(new AuthFail(err.error));
                }
                if (err.status === 400) {
                    return Observable.throw(new BadInput(err.error));
                }
                if (err.status === 404) {
                    return Observable.throw(new NotFoundError());
                }
                if (err.status === 403) {
                    return Observable.throw(new AccessDenied());
                }
                return Observable.throw(new AppError(err));
            }
        });
    }
}

-denied.ts

import { AppError } from './app-error';
export class AccessDenied extends AppError {
    constructor(public originalError?: any) {
        super();
        console.log('inside acces denied constructor');
        // super.handleError("superrrrr"); // this also doesn't work
    }

    public handleError(): void {
        console.log('handleError: ', );
        super.handleError("Access denined error occured");
    }
}

-error.ts

import { Inject, Injector } from "@angular/core";

import { ToastrService } from "ngx-toastr";

export class AppError {
    toastrService: ToastrService;
    constructor(public originalError?: any, private injector?: Injector) {
        this.toastrService = this.injector.get(ToastrService);
    }

    // NOTE: using getter seems impossible to access in child so add the same in constructor
    // get toastrService(): ToastrService {
    //  return this.injector.get(ToastrService);
    // }

    public handleError(msg: string): void {
        this.toastrService.error(`Error Message: ${msg}`,
            "Error", {
                closeButton: true,
                timeOut: 5000,
                onActivateTick: true
            }
        );
    }

}


core.es5.js:1020 ERROR TypeError: Cannot read property 'get' of undefined 
    at AccessDenied.AppError (app-error.ts:8) 
    at new AccessDenied (access-denied.ts:6)  
    at CatchSubscriber.eval [as selector] (error.interceptor.ts:61) 
    at CatchSubscriber.error (catchError.js:105)
    at XMLHttpRequest.onLoad (http.es5.js:1739)
    at ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.es5.js:3881)
    at ZoneDelegate.invokeTask (zone.js:420)
    at Zone.runTask (zone.js:188)
    at ZoneTask.invokeTask [as invoke] (zone.js:496)
+4
2

AccessDenied AppError. super() , injector undefined, injector AppError, .

:

constructor(private injector: Injector, public originalError?: any) {
    this.toastrService = this.injector.get(ToastrService);
}

AccessDenied. new AccessDenied(injector).

, AppError , . , , err instanceof AppError, , handleError.

handleError ToastrService , AppError. , Access denied error occurred, AppError , .

+1

ToastrService . , Angular , . , , ToastrService AppError .

ErrorHandler, , AppError, ToastrService .

- ( ):

-error.ts

import { Inject, Injector } from "@angular/core";

import { ToastrService } from "ngx-toastr";

export class AppError {
    constructor(public message?: string, public title?: string) { }

}

-denied.ts

import { AppError } from './app-error';
export class AccessDenied extends AppError {
    constructor(message?: string, title?: string) {
        super(message, title);
    }
}

-error.handler.ts

import { ErrorHandler, Inject, Injector, Injectable } from "@angular/core";
import { ToastrService } from "ngx-toastr";
import { AppError } from './app-error';

@Injectable()
export class AppErrorHandler extends ErrorHandler {

    constructor(@Inject(Injector) private injector: Injector) {
        super(true);
    }

    // Need to get ToastrService from injector rather than constructor injection to avoid cyclic dependency error
    private get toastrService(): ToastrService {
        return this.injector.get(ToastrService);
    }

    public handleError(error: any): void {
        if (error instanceof AppError) {
            this.toastrService.error(
                error.message,
                error.title,
                {
                    closeButton: true,
                    timeOut: 5000,
                    onActivateTick: true
                }
            );
        }

        super.handleError(error);
    }
}

app.module.ts

@NgModule({
  // Your imports, declarations, bootstrap, etc.
  // ...

  providers: [
    // Other providers...

    {
      provide: ErrorHandler,
      useClass: AppErrorHandler
    }
  ]
})
export class AppModule {}
0

Source: https://habr.com/ru/post/1694582/


All Articles