4

我正在研究角度的全局错误处理程序,我的项目的要求也是在错误时显示一个模态窗口,以便用户可以报告是否有问题并且我们可以修复它。除非模板中发生错误,否则它工作正常。在这种情况下,更改检测基本上被破坏了,它不更新绑定,因此 Material Modal Dialog 显示为空。我试图用谷歌搜索并检查 ngDebugContext 中的所有可用数据,但没有什么能回答我的问题。关键是如果模板中发生错误(或者我们可以知道更改检测是否通常已失效),那么我只会显示警报。作为最后的解决方案,我将只使用静态模板创建模态组件,其中文本将被硬编码并在出现任何未处理的错误时显示。

4

2 回答 2

3

最后,我们通过使用更改检测被破坏的事实解决了这个问题,并使用角度绑定在模态中创建了一个始终隐藏的元素[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>
<!---->
于 2018-05-24T11:21:42.263 回答
0

您可以像这样在全局级别定义自定义错误处理程序:

自定义错误处理程序.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

于 2018-05-24T12:31:05.650 回答