Как определить, произошла ли ошибка в шаблоне в угловых?

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

2 ответа

Решение

В конце концов, мы решили это, используя тот факт, что обнаружение изменений не работает, и создали всегда скрытый элемент в модале, используя угловое связывание. [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>
<!---->

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

заказ ОШИБОК 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

Другие вопросы по тегам