Как определить, произошла ли ошибка в шаблоне в угловых? - PullRequest
0 голосов
/ 24 мая 2018

Я работаю над глобальным обработчиком ошибок в angular, и мой проект также должен показывать модальное окно об ошибке, чтобы пользователь мог сообщить, что что-то не так, и мы можем это исправить.Работает нормально, если в шаблоне не происходит ошибкаОбнаружение изменений в основном нарушается, в этом случае оно не обновляет привязки, поэтому диалог выбора материала отображается пустым.Я попытался погуглить и проверил все доступные данные в ngDebugContext, но ничего не смог ответить на мой вопрос.Дело в том, что в случае ошибки в шаблоне (или, может быть, мы можем узнать, вообще ли обнаружена ошибка), я бы просто отобразил предупреждение.В качестве последнего решения я просто создаю модальный компонент со статическим шаблоном, где текст будет жестко закодирован и отображать его в случае любой необработанной ошибки.

Ответы [ 2 ]

0 голосов
/ 24 мая 2018

Вы можете определить собственный обработчик ошибок на глобальном уровне, например:

custom-error-handler.service.ts

import { ErrorHandler, Injectable } from '@angular/core';

@Injectable()
export class CustomErrorHandler implements ErrorHandler {
  constructor() { }

  handleError(error) {
    // your custom error handling logic
    console.log('GLOBAL ERROR CAUGHT: ', error.toString())
  }
}

app.module.ts

import { NgModule, ErrorHandler } from '@angular/core';
import { CustomErrorHandler } from './custom-error-handler.service';

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

Но вы не можете поймать опечатку с переменной с этим.И это имеет смысл.Если взять следующий компонент:

TS

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  name = 'Angular 6';

  triggerError() {
    throw new Error('Some error');
  }
}

HTML

<!-- variable is defined as `name` but typo -->
<p>
  Name: {{ nam || 'Default name' }}
</p>

<button (click)="triggerError()">Trigger error caught by global/custom error handler</button>

Здесь мы получаем впредставление "Имя по умолчанию", потому что nam просто не определено.Это не настоящая ошибка.Попробуйте написать undefined в консоли браузера или в контексте nodejs, хорошо.Это не ошибка.

То есть, если вы попытаетесь получить доступ к свойству, которое не определено для объекта, вы получите ошибку.Поэтому, если вы обновите HTML-код до:

<p>
  Name: {{ nam.someUndefinedProp || 'Default name' }}
</p>

Вы заметите, что CustomErrorHandler перехватил эту ошибку.

Но в целом я бы не советовал вам это делать.Это должно быть подтверждено, но, возможно, AOT сможет это отловить, а если нет, вам просто нужно написать какие-нибудь интеграционные или E2E-тесты, которые бы это поймали.

Вот рабочий пример для stackblitz:

https://stackblitz.com/edit/angular-sipcki?file=src%2Fapp%2Fapp.component.html

0 голосов
/ 24 мая 2018

В конце концов, мы решили это, используя тот факт, что обнаружение изменений нарушено, и создали всегда скрытый элемент в модале, используя угловое связывание [hidden]='true', но поскольку обнаружение изменений нарушается, оно будет игнорироваться, поэтому текст внутри него будетотображаться, и таким образом мы можем даже показать очень конкретное сообщение, когда приложение действительно рухнуло, как

<!-- This part is fallback for unhandled error which happens during change detection in the template -->
    <div class='crash-error-heading' [hidden]='true'>
      <h2>Something went really wrong</h2>
    </div>
<!---->
...