Как определить, произошла ли ошибка в шаблоне в угловых?
Я работаю над глобальным обработчиком ошибок в 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