为什么全局错误处理程序中的烤面包机服务在Angular4 / 5/6中不起作用?

Abh*_*bhi 7 zone http-status-code-401 typescript angular angular2-toaster

我的要求是在应用程序组件加载之前通过调用两个Rest Api加载一些数据。如果API出现任何错误,则会在Toaster(angular2-toaster)中显示消息。

在加载应用程序组件之前,将执行以下AppLoadService

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import 'rxjs/add/operator/toPromise';
import { APP_SETTINGS } from 'app/app-settings/settings';

@Injectable()
export class AppLoadService {

constructor(private httpClient: HttpClient) { }

loadLabs(): Promise<any> {
    return new Promise((resolve, reject) => {
        this.httpClient.get(`/api/v1/api/lab`)
            .toPromise()
            .then((res: any) => {
                APP_SETTINGS.labs = res;
                resolve();
            })
            .catch((err: any) => {
                reject(err);
            });
    });
}
/////////////////******************////////////////////////////
getSettings(): Promise<any> {
    return new Promise((resolve, reject) => {
        this.httpClient.get(`assets/settings/config.json`)
            .toPromise()
            .then((config: any) => {
                APP_SETTINGS.loginURL = config["login"];
                console.log(`config.json loaded:: `, APP_SETTINGS);
                resolve();
            })
            .catch((err: any) => {
                reject(err);
            });
    });
 }
Run Code Online (Sandbox Code Playgroud)

我的App模块文件如下

    export function createTranslateLoader(http: Http) {
        return new TranslateStaticLoader(http, './assets/i18n', '.json');
    }


    @NgModule({
    declarations: [
        AppComponent, CustomDateRangePickerComponent
    ],
    imports:  [
            // coreModules: //
            BrowserModule,
            BrowserAnimationsModule,
            ToasterModule,
            HttpClientModule,
            FormsModule,
            CommonModule, //<====added

            //thirdPartyModules:
            // ToastyModule,
            BootstrapModalModule,
            //appModules: //
            AppRoutingModule,
            FooterModule,
            ErrorModule,
            AccessDeniedModule,
            NotFoundModule,
            AppLoadModule, //Startupdata before APP loaded
            RouterModule.forRoot([]),
            TranslateModule.forRoot({ provide: TranslateLoader, useFactory: (createTranslateLoader), deps: [Http] })
    ],
    providers: [
        ToasterService,
        StartupService,
        ResponseStatusesService,
        LocalStorageService,
        ApplicationSettingsService,
        LabSelectionService,
        AccountService,
        AuthService,
        AlertService,
        AuthGuard,
        RolesGuard,
        FeaturebasedGuard,
        ErrorLogService,
        {
            provide: ErrorHandler,
            useClass: GlobalErrorsHandler
        },
        {
            provide: HTTP_INTERCEPTORS,
            useClass: AppHttpInterceptor,
            multi: true
        },
        {
            provide: LocationStrategy,
            useClass: HashLocationStrategy
        },
    ],
    exports: [TranslateModule],
    bootstrap: [AppComponent]
    })

    export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

GlobalErrorHandler.ts

@Injectable()
export class GlobalErrorsHandler extends ErrorHandler {
constructor(
    private injector: Injector,
    private errorLogService: ErrorLogService

) {
    super();
    alert('GlobalErrorsHandler');

}
handleError(error: Error | HttpErrorResponse) {
    debugger;
    let toaster = this.injector.get(ToasterService);
    toaster.pop("head", "body");
}
}
Run Code Online (Sandbox Code Playgroud)

AppComponent.html

<toaster-container [toasterconfig]="ang2toasterconfig"></toaster-container>

<router-outlet></router-outlet>
Run Code Online (Sandbox Code Playgroud)

拦截器也有同样的问题

            import { Injectable, Injector } from '@angular/core';
            import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse, HttpErrorResponse } from '@angular/common/http';
            import { Observable } from 'rxjs/Observable';
            import 'rxjs/add/operator/do';
            import 'rxjs/add/operator/catch';
            import 'rxjs/add/observable/throw';
            import { ToasterService } from 'angular2-toaster';
            import { AuthService } from 'app/blocks/auth/auth.service';
            import { TranslateService } from 'ng2-translate';
            import { AlertService } from '../../core/services/common';


            @Injectable()
            export class AppHttpInterceptor implements HttpInterceptor {

                constructor(private injector: Injector) { }

                intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
                    debugger;
                    console.log(req);
                    if (!window.navigator.onLine) { // check to see if there's internet
                        // if there is no internet, throw a HttpErrorResponse error
                        // since an error is thrown, the function will terminate here
                        return Observable.throw(new HttpErrorResponse({ error: 'NO_INTERNET' }));
                    } else {
                        // else return the normal request
                        return this.handleResponse(next, req);
                    }


                }
                handleResponse(next, req) {
                    return next.handle(req)
                        .do((ev: HttpEvent<any>) => {
                            if (ev instanceof HttpResponse) {
                            }
                        })
                        .catch((response: any) => {
                            if (response instanceof HttpErrorResponse) {
                                console.log('response in the catch: ', response);
                                this.handleReponseExceptions(response);
                            }
                            return Observable.throw(response);
                        });
                }
                handleReponseExceptions(exception) {
                    let toaster = this.injector.get(ToasterService);
                    let translate = this.injector.get(TranslateService);

                    // TOASTER NOT WORKING AND TRANSLATE NOT WORKING
                    toaster.pop("test","test");

                    this.translate.get(["test", "test"]).subscribe(res => {
                        //NOT FETCHING FROM en.json
                    });

                }

            }
Run Code Online (Sandbox Code Playgroud)

据我所知,toaster.pop('','')方法是在烤面包机容器加载之前调用的。如何解决这个问题。根组件是App组件,我在其中放置了烤面包机容器。请向我建议解决此问题的体系结构。

还有一个,我需要处理不同的错误...在本地错误处理程序(组件级别)中还是在全局错误处理程序中或在拦截器中?

错误示例:400,404,500+ ...等

Update1:​​按照David注释更改了如下代码,但控制台中仍未显示任何容器.....消息,并且看不到烤面包机

使用“ angular2-toaster”:“ ^ 6.1.0”

在此处输入图片说明

在此处输入图片说明

这些是API调用,将在应用程序组件之前触发 在此处输入图片说明

在此处输入图片说明

Dav*_*d L 5

这被记录angular2-toaster的自述由于次数这种情况发生时,它会导致混乱。

这是由于Angular如何在错误处理程序中处理UI调度(或者缺少UI调度)引起的。

handleError函数的执行超出Angular区域的大小。您需要明确地告诉Angular在区域的上下文中运行pop调用。

export class AppErrorHandler implements ErrorHandler {
    constructor(
        private toasterService: ToasterService,
        private ngZone : NgZone) { }

    handleError(error: any): void {
        this.ngZone.run(() => {
            this.toasterService.pop('error', "Error", error);
        });  
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 像上面一样尝试过,但是不起作用 (4认同)