写在前面

代码写得再好,始终都无法完整的处理所有可能产生异常,特别是生产环境中的应用,很大一部分是数据来自用户、远程,很难保证所有数据都按程序规定的产生。事实上,除非测试人员发现或者客户报告,否则都无法得知。因此,将应用产生的未可知异常进而上报是非常重要的环节。

Angular 默认情况下也提供了全局的异常管理,当发生异常时,会把它扔到 Console 控制台上。如果你在使用 NG-ZORRO 时,可能经常就会遇到 ICON 未加载的异常消息,这也是异常消息的一种:

core.js:5980 ERROR Error: [@ant-design/icons-angular]:the icon setting-o does not exist or is not registered.
 at IconNotFoundError (ant-design-icons-angular.js:94)
 at MapSubscriber.project (ant-design-icons-angular.js:222)
 at MapSubscriber._next (map.js:29)
 at MapSubscriber.next (Subscriber.js:49)
 at RefCountSubscriber._next (Subscriber.js:72)
 at RefCountSubscriber.next (Subscriber.js:49)
 at Subject.next (Subject.js:39)
 at ConnectableSubscriber._next (Subscriber.js:72)
 at ConnectableSubscriber.next (Subscriber.js:49)
 at CatchSubscriber.notifyNext (innerSubscribe.js:42)

而 Angular 是通过 ErrorHandler 统一管理异常消息,而且只需要覆盖其中的 handleError 方法并重新处理异常消息即可。

ErrorHandler

首先创建一个 custom-error-handler.ts 文件:

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

@Injectable()
export class CustomErrorHandler extends ErrorHandler {
 handleError(error: any): void {
 super.handleError(error);
 }
}

CustomErrorHandler 可以完整的获取当前用户数据、当前异常消息对象等,并允许通过 HttpClient 上报给后端。

以下是 NG-ALAIN 的文档站,由于是使用 Google Analytics 来分析,只需要将异常消息转给 onerror 即可:

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

@Injectable()
export class CustomErrorHandler extends ErrorHandler {
 constructor(@Inject(DOCUMENT) private doc: any) {
 super();
 }

 handleError(error: any): void {
 try {
  super.handleError(error);
 } catch (e) {
  this.reportError(e);
 }
 this.reportError(error);
 }

 private reportError(error: string | Error): void {
 const win = this.doc.defaultView as any;
 if (win && win.onerror) {
  if (typeof error === 'string') {
  win.onerror(error);
  } else {
  win.onerror(error.message, undefined, undefined, undefined, error);
  }
 }
 }
}

最后,在 AppModule 模块内注册 CustomErrorHandler :

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

结论

事实上还有一项非常重要的工作,生产环境中都是打包压缩过后的,换言之所产生的异常消息也是无法与实际代码行数相同的数字,这就需要 SourceMap 的支持,当然正常的生产环境是不会发布这份文件的,所以如果想要得到正确的行列数,还是需要借助一层中间层,在后端利用 source-map 模块来解析出真正的行列数值。

Angular 的依赖注入(DI)系统可以使我们快速替换一些 Angular 内置模块,从而实现在不修改业务层面时快速解决一些特殊需求。

总结

标签:
angular异常错误,angular异常捕获

免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
白云城资源网 Copyright www.dyhadc.com

评论“Angular处理未可知异常错误的方法详解”

暂无“Angular处理未可知异常错误的方法详解”评论...

稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!

昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。

这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。

而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?