如何检测 angular 中的模板是否发生错误?
How to detect if error happened in template in angular?
我正在 angular 中开发全局错误处理程序,我的项目的要求也是在错误时显示模态 window,以便用户可以报告是否有问题,我们可以修复它。除非模板中发生错误,否则它工作正常。在这种情况下,更改检测基本上被破坏了,它不更新绑定,因此 Material 模态对话框显示为空。我试着 google 并检查了 ngDebugContext 中的所有可用数据,但没有什么可以回答我的问题。要点是,万一模板中发生错误(或者我们可以知道更改检测是否通常已死),那么我将只显示警报。作为最后的解决方案,我将使用静态模板创建模态组件,其中文本将被硬编码并在出现任何未处理的错误时显示。
最后,我们通过使用更改检测被破坏的事实解决了它,并使用 angular 绑定 [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>
这里我们进入渲染视图 "Default name" 因为 nam
只是未定义。这不是实际错误。尝试在浏览器控制台或 nodejs 上下文中写入 undefined
,没问题。这不是错误。
也就是说,如果您尝试访问未定义对象上的 属性,则会出现错误。因此,如果您将 HTML 更新为:
<p>
Name: {{ nam.someUndefinedProp || 'Default name' }}
</p>
您会注意到 CustomErrorHandler
发现了那个错误。
但一般来说,我不建议你这样做。它必须得到确认,但也许 AOT 可以捕获它,如果它不能捕获它,那么您应该编写一些集成或 E2E 测试来捕获它。
这是一个关于 stackblitz 的工作示例:
https://stackblitz.com/edit/angular-sipcki?file=src%2Fapp%2Fapp.component.html
我正在 angular 中开发全局错误处理程序,我的项目的要求也是在错误时显示模态 window,以便用户可以报告是否有问题,我们可以修复它。除非模板中发生错误,否则它工作正常。在这种情况下,更改检测基本上被破坏了,它不更新绑定,因此 Material 模态对话框显示为空。我试着 google 并检查了 ngDebugContext 中的所有可用数据,但没有什么可以回答我的问题。要点是,万一模板中发生错误(或者我们可以知道更改检测是否通常已死),那么我将只显示警报。作为最后的解决方案,我将使用静态模板创建模态组件,其中文本将被硬编码并在出现任何未处理的错误时显示。
最后,我们通过使用更改检测被破坏的事实解决了它,并使用 angular 绑定 [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>
这里我们进入渲染视图 "Default name" 因为 nam
只是未定义。这不是实际错误。尝试在浏览器控制台或 nodejs 上下文中写入 undefined
,没问题。这不是错误。
也就是说,如果您尝试访问未定义对象上的 属性,则会出现错误。因此,如果您将 HTML 更新为:
<p>
Name: {{ nam.someUndefinedProp || 'Default name' }}
</p>
您会注意到 CustomErrorHandler
发现了那个错误。
但一般来说,我不建议你这样做。它必须得到确认,但也许 AOT 可以捕获它,如果它不能捕获它,那么您应该编写一些集成或 E2E 测试来捕获它。
这是一个关于 stackblitz 的工作示例:
https://stackblitz.com/edit/angular-sipcki?file=src%2Fapp%2Fapp.component.html