22 | 异常处理中间件:区分真异常与逻辑异常

这一节我们来讲解一下错误处理的最佳实践

系统里面异常处理,ASP.NET Core 提供了四种方式

1、异常处理页

2、异常处理匿名委托方法

3、IExceptionFilter

4、ExceptionFilterAttribute

源码链接:
https://github.com/witskeeper/geektime/tree/master/samples/ExceptionDemo

Startup 的 Configure 方法

if (env.IsDevelopment())
{// 开发环境下的异常处理页app.UseDeveloperExceptionPage();
}

控制器抛出异常

throw new Exception("报个错");

启动程序,可以看到一个错误页

这个错误页会输出我们当前请求的详细信息和错误的详细信息,这种页面是不适合给用户看到的,所以这样的错误页在生产环境是需要关闭的

以下是正常处理错误页的方式:

// 第一种方式就是定义错误页的方式
app.UseExceptionHandler("/error");

定义一个接口 IKnownException

namespace ExceptionDemo.Exceptions
{public interface IKnownException{public string Message { get; }public int ErrorCode { get; }public object[] ErrorData { get; }}
}

默认实现 KnownException

namespace ExceptionDemo.Exceptions
{public class KnownException : IKnownException{public string Message { get; private set; }public int ErrorCode { get; private set; }public object[] ErrorData { get; private set; }public readonly static IKnownException Unknown = new KnownException { Message = "未知错误", ErrorCode = 9999 };public static IKnownException FromKnownException(IKnownException exception){return new KnownException { Message = exception.Message, ErrorCode = exception.ErrorCode, ErrorData = exception.ErrorData };}}
}

为什么需要定义这样一个类型呢?

因为通常情况下我们系统里面的异常和我们业务逻辑的异常是不同的,业务逻辑上面的判断异常,比如说输入的参数,订单的状态不符合条件,当前账户余额不足,这样子的信息我们有两种处理方式:

一种处理方式就是对不同的逻辑输出不同的业务对象

还有一种方式就是对于异常的这种业务逻辑,输出一个异常,用异常来承载逻辑的特殊分支,这个时候就需要识别出来哪些是业务的异常,哪些是不确定的未知的异常,比如说网络的请求出现了异常,MySql 的连接闪断了,Redis 的连接出现了异常

接着通过定义一个错误页来承载错误信息,比如我们的 ErrorController,它只有一个页面,它的作用就是输出错误信息

namespace ExceptionDemo.Controllers
{[AllowAnonymous]public class ErrorController : Controller{[Route("/error")]public IActionResult Index(){// 获取当前上下文里面报出的异常信息var exceptionHandlerPathFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();var ex = exceptionHandlerPathFeature?.Error;// 特殊处理,尝试转换为 IKnownExceptionvar knownException = ex as IKnownException;// 对于未知异常,我们并不应该把错误异常完整地输出给客户端,而是应该定义一个特殊的信息 Unknown 传递给用户// Unknown 其实也是一个 IKnownException 的实现,它的 Message = "未知错误", ErrorCode = 9999// 也就是说我们在控制器 throw new Exception("报个错"); 就会看到错误信息if (knownException == null){var logger = HttpContext.RequestServices.GetService<ILogger<MyExceptionFilterAttribute>>();// 我们看到的信息是未知错误,但是在我们的日志系统里面,我们还是记录的原有的异常信息logger.LogError(ex, ex.Message);knownException = KnownException.Unknown;}else// 当识别到异常是已知的业务异常时,输出已知的异常,包括异常消息,错误状态码和错误信息,就是在 IKnownException 中的定义{knownException = KnownException.FromKnownException(knownException);}return View(knownException);}}
}

View

@model ExceptionDemo.Exceptions.IKnownException
@{ViewData["Title"] = "Index";
}<h1>错误信息</h1><div>Message:<label>@Model.Message</label></div>
<div>ErrorCode<label>@Model.ErrorCode</label></div>

启动程序之后可以看到自定义的错误页已经成功渲染出来了

这就是第一种处理错误的方式

.NET Core开发实战(第22课:异常处理中间件:区分真异常与逻辑异常)--学习笔记(上)...相关推荐

  1. .NET Core开发实战(第5课:依赖注入:良好架构的起点)--学习笔记(上)

    05 | 依赖注入:良好架构的起点 为什么要使用依赖注入框架 借助依赖注入框架,我们可以轻松管理类之间的依赖,帮助我们在构建应用时遵循设计原则,确保代码的可维护性和可扩展性 ASP.NET Core ...

  2. .NET Core开发实战(定义API的最佳实践)Source Generators版

    前言 极客时间上的<.NET Core开发实战>是一门非常好的课程,作者肖伟宇在第31课(https://time.geekbang.org/course/detail/100044601 ...

  3. 三维电子沙盘无人机倾斜摄影开发教程第22课

    三维电子沙盘无人机倾斜摄影开发教程第22课 gis3d.MapGo(103, 30, 19); //第一次跳转会有点慢,主要是获取数据,如果是用的公网服务器可能会卡一下.第二次就不会了 运行上面的代码 ...

  4. gram矩阵的性质_第十七课:正交矩阵和GramSchmidt正交化——MIT线性代数课程学习笔记...

    公众号关注  "DL_NLP" 设为 "星标",重磅干货,第一时间送达! ◎ 原创 | 深度学习算法与自然语言处理 ◎ 作者 | 丁坤博 一. 知识概要 这一节 ...

  5. ASP.NET Core分布式项目实战(业务介绍,架构设计,oAuth2,IdentityServer4)--学习笔记...

    任务4:第一章计划与目录 敏捷产品开发流程 原型预览与业务介绍 整体架构设计 API 接口设计 / swagger Identity Server 4 搭建登录 账号 API 实现 配置中心 任务5: ...

  6. python的程序异常类型,Python3.4学习笔记之类型判断,异常处理,终止程序操作小结...

    本文实例讲述了Python3.4类型判断,异常处理,终止程序操作.分享给大家供大家参考,具体如下: python3.4学习笔记 类型判断,异常处理,终止程序,实例代码: #idle中按F5可以运行代码 ...

  7. .NET Core开发实战(第22课:异常处理中间件:区分真异常与逻辑异常)--学习笔记(下)...

    接下来介绍使用代理方法的方式,也就是说把 ErrorController 整段逻辑直接定义在注册的地方,使用一个匿名委托来处理,这里的逻辑与之前的逻辑是相同的 app.UseExceptionHand ...

  8. .NET Core开发实战(第33课:集成事件:使用RabbitMQ来实现EventBus)--学习笔记(上)...

    33 | 集成事件:使用RabbitMQ来实现EventBus 这一节我们来讲解如何通过 CAP 组件和 RabbitMQ 来实现 EventBus 要实现 EventBus,我们这里借助了 Rabb ...

  9. 笔记合并_.NET Core开发实战(第23课:静态文件中间件:前后端分离开发合并部署骚操作)学习笔记(上)...

    23 | 静态文件中间件:前后端分离开发合并部署骚操作 我们先来看一下静态文件中间件有哪些能力 1.支持指定相对路径 2.支持目录的浏览 3.支持设置默认文档 4.支持多目录映射 源码链接: http ...

最新文章

  1. 机器学习算法(3:决策树算法)
  2. django错误参考
  3. 哈理工计算机分数线2020,2021哈尔滨理工大学研究生分数线一览表(含2019-2020历年复试)...
  4. 关于如何存储便于网上浏览的电子书籍
  5. 微信小程序中实现瀑布流布局和无限加载
  6. 【LeetCode】【HOT】438. 找到字符串中所有字母异位词(滑动窗口)
  7. 【Elasticsearch】es Timelion是Kibana中时间序列的可视化工具
  8. 码农们的聚餐,会复杂到什么程度?
  9. python 笔记 之 线程锁
  10. HDU 3037 Saving Beans [Lucas定理]
  11. android 简介动画,android动画简介
  12. linux生成手机号码字典,字典生成器,木头超级字典生成器
  13. 前端实现批量下载图片(自己的服务器需设置可跨域请求)
  14. 蓝牙硬件设备没有链接到计算机,电脑未发现蓝牙硬件设备怎么办
  15. 基于STM32的RGB调色器——STM32程序和Qt上位机全开源
  16. 如何使用 Linux 内核定时器
  17. MMFNet: A Multi-modality MRI Fusion Network for Segmentation of Nasopharyngeal Carcinoma
  18. 访问网址 token的格式_一文彻底搞懂Cookie、Session、Token到底是什么
  19. 基于微信小程序的教务管理系统(教务管理小程序)
  20. c++游戏别踩白块课程设计

热门文章

  1. Delphi中的容器类(3)
  2. 【小安翻唱】凉宫春日的忧郁--冒険でしょでしょ第五届外语歌曲大赛助兴节目~绫魂论坛送aya的生日礼物筹备开始~...
  3. JSP数据库连接方式总结
  4. Mysql-高可用集群[MyCat中间件使用](三)
  5. 如何解决高并发,秒杀问题
  6. java B2B2C Springcloud多租户电子商城系统-Spring Cloud Sleuth
  7. hibernate自定义校验器使用(字段在in范围之内)
  8. Cloudstack部署
  9. 软件工程心理学之1----开篇
  10. Avalonia跨平台入门第十五篇之ListBox聊天窗口