用VSCode开发一个asp.net core 2.0+angular 5项目(4): Angular5全局错误处理
发布日期:2021-09-11 05:52:28 浏览次数:32 分类:技术文章

本文共 5179 字,大约阅读时间需要 17 分钟。

第一部分: 

第二部分: 

第三部分: 

这篇文章将介绍angular 5的全局错误处理.

需要使用到代码: 

angular 5 全局错误处理

参考文档: 

首先按照文档在客户端项目建立app.error-handler.ts 文件:

import { ErrorHandler } from '@angular/core';export class AppErrorHandler implements ErrorHandler {    handleError(error: any): void {        console.log('ERROR Occurred.');    }}

这里, 我们只写log.

然后在app.module里面注册:

providers: [    TvNetworkService,    { provide: ErrorHandler, useClass: AppErrorHandler }  ],

然后把tv-network-list.component.ts里面到一个错误处理删除掉:

然后在后端到Controller里面抛一个异常:

然后我们试一下:

可以看到, 这个全局错误处理器正常到工作了.

先别急, 让我们在errorhandler里面使用toastr试试.

app.error-handler.ts:

import { ErrorHandler } from '@angular/core';import { ToastrService } from 'ngx-toastr';export class AppErrorHandler implements ErrorHandler {    constructor(private toastr: ToastrService) { }    handleError(error: any): void {        // console.log('ERROR Occurred.');        this.toastr.error('发生了错误');    }}

 

而这时回到浏览器之后, 发生了错误:

之所以发生这个错误, 是因为AppErrorHandler在angular引入Toastr模块之前就初始化了.

我们可以这样处理:

import { ErrorHandler, Injectable, Injector, Inject } from '@angular/core';import { ToastrService, Toast } from 'ngx-toastr';@Injectable()export class AppErrorHandler implements ErrorHandler {    constructor(private injector: Injector) { }    private get toastr(): ToastrService {        return this.injector.get(ToastrService);    }    handleError(error: any): void {        this.toastr.error('发生了错误');    }}

使用Injector来手动注入ToastrService.

回到浏览器:

并没有弹出错误信息!!!!, 但是来回切换菜单后, 开始显示错误信息了, 貌似有点迟钝.

这是什么原因呢? 首先, 我们得了解以下这个东西:

Zone

首先到首先, 需要了解以下execution context, 程序执行到上下文, 但是这些东西到定义看了之后可能会让人迷糊. 所以还是先看这段代码吧:

const Zone = {  run: (callback) => {    if (this.beforeTask) {      this.beforeTask();    }    callback();    if (this.afterTask) {      this.afterTask();    }  }};Zone.beforeTask = () => {  console.log('Before Task.');};Zone.afterTask = () => {  console.log('After Task.');};Zone.run(() => {  console.log('Running...');});

 

就是定义一个Zone, 它到run方法可以执行某个回调函数, 回调函数到前后还可以有一些预定义的函数, 如果它们存在就会被执行. 通过定义这些函数的内容, 我们就可以在执行run的回调前后添加自定义逻辑了.

回到Angular, angular的变化检测(Change Detection)功能就用到了这些东西.

比如angular的一个component有一个click事件, click()方法里更新了某些属性的值, 这个时候angular就需要进行变化检测, 如果真的发生了变化, 那么angular 就会更新dom, 这样我们就能看见页面的变化了. Angular用了这个猴子补丁, 使之运行在Zone里面, 当点击按钮的时候, 这段代码总是在Zone里面执行, 在执行完click处理方法之后, angular会执行变化检测动作.

angular应该是这样来进行猴子补丁的:

const Zone = {  run: (callback) => {    if (this.beforeTask) {      this.beforeTask();    }    callback();    if (this.afterTask) {      this.afterTask();    }  }};Zone.beforeTask = () => {  console.log('Before Task.');};Zone.afterTask = () => {  console.log('After Task.');};Zone.run(() => {  console.log('Running...');});var _setTimeout = setTimeout;setTimeout = (callback, timeout) => {  Zone.run(() => {    _setTimeout(callback, timeout);  });};click(() => {  console.log('设置Timeout');});

由于这个是异步的, 所以打印到控制台到顺序可能是: Before Task, After Task, 设置Timeout.

js运行时里, 有一个信息队列. 任何时候出现一个异步操作, 队列里就会推进去一条信息, js运行时会训话这个队列, 一个个把消息推出队列, 然后调用这个消息到回调函数. 对于这个例子来说就是setTimeout().

所以就出现了Zone.js这个库.

Zone.js就是一个执行的上下文, 它可以在不同的异步操作之间进行持久性传递.

Angular就使用了这个库, 在它之上建立了ngZone这个模块. 就这样angular在发生异步操作后进行到了变化检测.

浏览器里面主要有这几种异步操作: dom事件, ajax请求, 定时回调之类的.

回到项目里的app.error-handler.ts:

这句话呢就跑出了angular zone的范围...

所以当错误发生的时候, toastr的error方法被调用了(状态改变了), 但是angular并不知道这个变化, 所以toastr通知没有显示.

那如何解决呢?

使用ngZone:

import { ErrorHandler, Injectable, Injector, Inject, NgZone } from '@angular/core';import { ToastrService, Toast } from 'ngx-toastr';@Injectable()export class AppErrorHandler implements ErrorHandler {    constructor(        private injector: Injector,        private ngZone: NgZone    ) { }    private get toastr(): ToastrService {        return this.injector.get(ToastrService);    }    handleError(error: any): void {        this.ngZone.run(() => {            this.toastr.error('发生了错误');        });    }}

下面试试页面:

这次没有任何问题了.

Logging Errors 记录错误 

您可以自己写一个后台api来记录日志, 但是这里我介绍一个专门做logging的云服务, sentry.io

首先请您自己注册账户. 

然后创建一个项目, 选择angular:

然后点击下面按钮Create Project.

然后它给出了安装和配置的说明:

首先执行命令安装.

然后, 配置:

import * as Raven from 'raven-js';import { BrowserModule } from '@angular/platform-browser';import { NgModule, ErrorHandler } from '@angular/core';import { AppComponent } from './app.component';Raven  .config('https://fa66d9390ab04c7f8e8c82ad0613fb4e@sentry.io/301095')  .install();@NgModule({  imports: [ BrowserModule ],  declarations: [ AppComponent ],  bootstrap: [ AppComponent ],  providers: [ { provide: ErrorHandler, useClass: AppErrorHandler } ]})export class AppModule { }

按照说明进行配置, 我们做一些调整, 这里红色部分是每个用户都不一样都.

最后修改app.error-handler.ts:

import { ErrorHandler, Injectable, Injector, Inject, NgZone } from '@angular/core';import { ToastrService, Toast } from 'ngx-toastr';import * as Raven from 'raven-js';@Injectable()export class AppErrorHandler implements ErrorHandler {    constructor(        private injector: Injector,        private ngZone: NgZone    ) { }    private get toastr(): ToastrService {        return this.injector.get(ToastrService);    }    handleError(error: any): void {        Raven.captureException(error);        this.ngZone.run(() => {            this.toastr.error('发生了错误');        });    }}

回到浏览器的错误页面, 触发错误后, 大约几分钟后, 来到sentry.io网站查看:

 

今天先写到这, 明天后天写以下 angular5上传文件到asp.net core web api.

转载地址:https://blog.csdn.net/weixin_34406061/article/details/85975340 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:bootstrap-multiselect.js如何动态更新select里的数据
下一篇:tomcat重启应用和tomcat重启是两回事。热部署就是重启应用

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年03月15日 20时28分05秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

html中列表菜单加文字请选择,html中下拉菜单 2019-04-21
读书郎平板中android,读书郎学生平板电脑怎么用 使用方法详解【图文】 2019-04-21
html5 调用摄像头 支持IE,JS调用本地摄像头拍照(兼容各大浏览器及IE8+) 2019-04-21
rust和gta5哪个吃配置_盘点4款Steam“自由度”很高的游戏,GTA5众所周知,目前最热门... 2019-04-21
es审计日志_elasticsearch 事务日志translog 2019-04-21
dw1510_超低温种子储存柜 2019-04-21
python用opencv计算汽车间距_计算机视觉:利用OpenCV和Python进行车辆计数详细步调... 2019-04-21
文件未找到mathpage.wll_解决MathPage.wll文件找不到的问题(找了好久的良心之作)... 2019-04-21
docker 查看容器磁盘大小_查看 docker 容器使用的资源 2019-04-21
python consul服务发现_Prometheus+Consul服务自动发现监控 2019-04-21
excel提取不规则字段_利用excel服务器来实现3级或者更多级的层级关联 2019-04-21
@autowired注解的作用_只因多看了一眼提示,又一次刷新了@Autowired注释的认知 2019-04-21
ab753变频器参数怎么拷贝到面板_变频器不知道如何上手,厂家教你如何三点搞定设置变频器参数... 2019-04-21
keepalived mysql双主架构图_华为CRM资深架构师:MySQL数据库架构和同步复制流程,看完就懂... 2019-04-21
gradle 本地maven仓库_Gradle的使用教程 2019-04-21
python制作表格处理软件_震惊!当Python遇到Excel后,将开启你的认知虫洞 2019-04-21
手写一个promise用法_手写系列之实现一个Promise 2019-04-21
数字拆分问题算法回溯_学会了回溯算法,我终于会做数独了 2019-04-21
广州刷脸支付骗局_刷脸支付是骗局?那可能你还不了解刷脸支付 2019-04-21
卸载源码安装的mysql_源码安装与卸载mysql 2019-04-21