用VSCode开发一个asp.net core 2.0+angular 5项目(4): Angular5全局错误处理

简介: 第一部分: http://www.cnblogs.com/cgzl/p/8478993.html 第二部分: http://www.cnblogs.com/cgzl/p/8481825.html 第三部分: https://www.

第一部分: http://www.cnblogs.com/cgzl/p/8478993.html

第二部分: http://www.cnblogs.com/cgzl/p/8481825.html

第三部分: https://www.cnblogs.com/cgzl/p/8525541.html

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

需要使用到代码: https://pan.baidu.com/s/1F0KjbwVE8_Tzfwy69Alp-A

angular 5 全局错误处理

参考文档: https://angular.io/api/core/ErrorHandler

首先按照文档在客户端项目建立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.iohttps://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.

下面是我的关于ASP.NET Core Web API相关技术的公众号--草根专栏:

目录
相关文章
|
16天前
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:<https://github.com/khellang/Scrutor>
37 5
|
1月前
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
42 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
1天前
|
开发框架 算法 中间件
ASP.NET Core 中的速率限制中间件
在ASP.NET Core中,速率限制中间件用于控制客户端请求速率,防止服务器过载并提高安全性。通过`AddRateLimiter`注册服务,并配置不同策略如固定窗口、滑动窗口、令牌桶和并发限制。这些策略可在全局、控制器或动作级别应用,支持自定义响应处理。使用中间件`UseRateLimiter`启用限流功能,并可通过属性禁用特定控制器或动作的限流。这有助于有效保护API免受滥用和过载。 欢迎关注我的公众号:Net分享 (239字符)
10 0
|
24天前
|
开发框架 缓存 .NET
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
26 3
|
1月前
|
自然语言处理 API C++
阿里通义推出SmartVscode插件,自然语言控制VS Code,轻松开发应用,核心技术开源!
SmartVscode插件深度解析:自然语言控制VS Code的革命性工具及其开源框架App-Controller
|
4月前
|
iOS开发 MacOS
【Mac系统】解决Vscode中LeetCode插件不能刷剑指offer题库
文章讨论了解决Mac系统中Vscode里LeetCode插件无法刷剑指Offer题库的问题,并提供了一些相关的使用技巧和资源链接。
258 1
|
1月前
|
开发工具 C++ git
利用VS Code提升开发效率的五大插件推荐
本文推荐了五款能显著提升开发效率的VS Code插件:ESLint用于代码质量和风格检查;Prettier自动格式化代码;GitLens增强Git功能;Live Server提供前端实时预览;Docker支持容器管理。
|
2月前
|
自然语言处理 JavaScript 开发者
通义灵码插件:VSCode 的智能编程助手
通义灵码插件:VSCode 的智能编程助手
753 3
|
2月前
|
前端开发 JavaScript 编译器
2024最新VSCode实用插件推荐,开发效率遥遥领先!超全面,快收藏~
【10月更文挑战第11天】2024最新VSCode实用插件推荐,开发效率遥遥领先!超全面,快收藏~
435 0
2024最新VSCode实用插件推荐,开发效率遥遥领先!超全面,快收藏~
|
4月前
|
前端开发 Go
vscode10大常用插件
本文介绍了前端开发中常用的工具及VSCode必备插件。推荐使用VSCode作为入门工具,并介绍了WebStorm和HBuilder等其他选项。VSCode插件包括:Open-In-Browser、live-server、Beautify、Code Runner、Image Preview、Path Intellisense、Turbo Console Log、css-auto-prefix、Bracket Pair Colorizer 和 Auto Rename Tag,这些插件能够显著提升开发效率和代码质量。此外,还提供了录制Gif图的工具GifCam。
162 5

热门文章

最新文章