如何处理/通知用户有关APP_INITIALIZER中不可恢复的异常的信息?

如何处理/通知用户有关APP_INITIALIZER中不可恢复的异常的信息?

问题描述:

我的Angular5应用在应用初始化期间从后端加载配置文件(APP_INITIALIZER).由于没有该应用程序无法运行该应用程序,因此我的目标是向用户显示一条消息,指出无法加载该配置.

My Angular5 app loads a config file from the backend during application initialization (APP_INITIALIZER). Since the app cannot be run without it, my goal is to show a message to the user that the config couldn't be loaded.

 providers: [ AppConfig,
        { provide: APP_INITIALIZER, useFactory: (config: AppConfig) => () => config.load(), deps: [AppConfig], multi: true },
        { provide: LocationStrategy, useClass: HashLocationStrategy},
        { provide: ErrorHandler, useClass: GlobalErrorHandler }]

AppConfig类应在应用加载之前从后端服务加载配置文件:

The AppConfig class should load a config file from a backend service before the app loads:

@Injectable()
export class AppConfig {

    private config: Object = null;
    constructor(private http: HttpClient) {}

    public getConfig(key: any) {
        return this.config[key];
    }


    public load() {
        return new Promise((resolve, reject) => {
            this.http.get(environment.serviceUrl + 'config/config')
                .catch((error: any) => {                  
                    return Observable.throw(error || 'Server error');
                })
                .subscribe((responseData) => {
                    this.config = responseData;
                    this.config['service_endpoint'] = environment.serviceUrl;                  
                    resolve(true);
                });
        });
    }
}

全局异常处理程序:

@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
    constructor( private messageService: MessageService) { }
    handleError(error) {
        // the AppConfig exception cannot be shown with the growl message since the growl component is within the AppComponent
        this.messageService.add({severity: 'error', summary: 'Exception', detail: `Global Exception Handler: ${error.message}`});

        throw error;
    }

}

如果无法加载配置文件,则会引发异常,并捕获并捕获该异常.重新放入全局异常处理程序中(在console.log()中未捕获HTTPErrorResponse,并且加载微调器永远挂起)

If the config file cannot be loaded, an exception is thrown, caught & rethrown in the global exception handler (uncaught HTTPErrorResponse in console.log()) and the loading spinner is hanging for ever)

由于AppComponent不会加载(没关系,因为没有配置就无法使用该应用程序),并且由于我的消息/"growl"组件是AppComponent的子组件,因此我无法显示给用户的消息.

Since the AppComponent does not get loaded (which is ok, since the app cannot be used without the configuration) and as my message/"growl" Component is a sub component of the AppComponent, I cannot display a message to the user.

在此阶段是否可以在index.html页中显示消息?我不想将用户重定向到不同于index.html的.html页面,因为用户将只在error.html上重新加载/f5.

Is there a way to show a message in the index.html page during this stage? I wouldn't like to redirect the user to a different .html page than the index.html, since the users will then just reload/f5 on the error.html.

在main.ts中,我以这种方式更改了引导程序:

In main.ts I have changed bootstrap in this way:

platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => {
    // error should be logged into console by defaultErrorLogger, so no extra logging is necessary here
    // console.log(err);
    // show error to user
    const errorMsgElement = document.querySelector('#errorMsgElement');
    let message = 'Application initialization failed';
    if (err) {
        if (err.message) {
            message = message + ': ' + err.message;
        } else {
            message = message + ': ' + err;
        }
    }
    errorMsgElement.textContent = message;
});

捕获任何发生的异常,并将消息设置为html元素.该元素在app.root标记的index.html中定义,例如

any occurred exceptions are caught and message is set into an html element. The element is defined in index.html in app-root tag, e.g.

<app-root><div id="errorMsgElement" style="padding: 20% 0; text-align: center;"></div> 
</app-root>

如果引导成功,则标记的内容将替换为angular.

The content of tag is replaced by angular, if bootstrap has been successful.