Подтвердить что ты не робот

Уведомлять об ошибке инициализации приложения Angular 2

Неперехваченное исключение (инжектор или просто случайная ошибка) в любом компоненте во время загрузки может привести к сбою начальной загрузки.

Из-за несовместимости браузера приложение может вообще не запускать процесс начальной загрузки.

Я ищу способ оповестить пользователя (с предупреждением, модальным и т.д.) о критической ошибке, которая произошла во время инициализации приложения Angular 2, поэтому пользователь может быть уверен, что приложение не просто загружается навсегда, но не работает по какой-то причине.

Какой хороший рецепт для обработки этого случая в Angular 2?

4b9b3361

Ответ 1

PlatformRef.bootstrapModule вернуть обещание, где мы можем .catch ошибку, а bootstrap (инициализация) приложения.

platformBrowserDynamic().bootstrapModule(<AppName>)
    .catch(er‌​r => console.error(err));

Была ошибка, которая была только что разрешена (changelog). Спасибо @estus, чтобы указать на это.

Ответ 2

Можно было исправить это с измененным отложенным рисунком. Однако решение основано на предположении, что бутстрапинг является синхронным и происходит в течение одного тика, что может быть неправильным.

Все еще не уверен, есть ли более эффективные подходы.

class InitDeferred {
  promise: Promise<any>;
  private fulfilled: boolean;

  constructor() {
    this.promise = new Promise((resolve, reject) => {
      setTimeout(() => this.fulfilled === true ? resolve() : reject('init error'));
    });
  }

  resolve() {
    this.fulfilled = true;
  }

  reject() {
    this.fulfilled = false;
  }
}

const initDeferred = new InitDeferred;
export default initDeferred;

@Injectable()
export class InitErrorHandler extends ErrorHandler {
    handleError(error: any): void {
      initDeferred.reject();
      super.handleError(error);
    }
}

@Component(...)
export class App extends OnInit {
  ngOnInit() {
    initDeferred.resolve();
  }
}

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

initDeferred.promise.catch(alert);
platformBrowserDynamic().bootstrapModule(AppModule);