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

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

app.UseExceptionHandler(errApp =>
{errApp.Run(async context =>{// 在 Features 里面获取异常var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();// 识别异常是否为 IKnownExceptionIKnownException knownException = exceptionHandlerPathFeature.Error as IKnownException;if (knownException == null){// 如果不是则记录并且把错误的响应码响应成 Http 500var logger = context.RequestServices.GetService<ILogger<MyExceptionFilterAttribute>>();logger.LogError(exceptionHandlerPathFeature.Error, exceptionHandlerPathFeature.Error.Message);knownException = KnownException.Unknown;context.Response.StatusCode = StatusCodes.Status500InternalServerError;}else{// 如果捕获到的是一个业务逻辑的异常,Http 响应码应该给是 200knownException = KnownException.FromKnownException(knownException);context.Response.StatusCode = StatusCodes.Status200OK;}// 然后再把响应信息通过 json 的方式输出出去var jsonOptions = context.RequestServices.GetService<IOptions<JsonOptions>>();context.Response.ContentType = "application/json; charset=utf-8";await context.Response.WriteAsync(System.Text.Json.JsonSerializer.Serialize(knownException, jsonOptions.Value.JsonSerializerOptions));});
});

为什么对于未知的异常要输出 Http 500,而对于业务逻辑的异常,建议输出 Http 200?

因为监控系统实际上会对 Http 的响应码进行识别,当监控系统识别到 Http 响应是 500 的比例比较高的情况下,会认为系统的可用性有问题,这个时候告警系统就会发出警告

对于已知的业务逻辑的这种正常的识别的话,用正常的 Http 200 来处理是一个正常的行为,这样就可以让监控系统更好的工作,正确的识别出系统的一些未知的错误信息,错误的告警,让告警系统更加的灵敏,也避免了业务逻辑的异常干扰告警系统

接下来看一下第三种,通过异常过滤器的方式

这种方式实际上是作用在 MVC 的整个框架的体系下面的,它并不是在中间件的最早期发生作用的,它是在 MVC 的整个生命周期里面发生作用,也就是说它只能工作在 MVC Web API 的请求周期里面

首先自定义一个 MyExceptionFilter

namespace ExceptionDemo.Exceptions
{public class MyExceptionFilter : IExceptionFilter{public void OnException(ExceptionContext context){IKnownException knownException = context.Exception as IKnownException;if (knownException == null){var logger = context.HttpContext.RequestServices.GetService<ILogger<MyExceptionFilterAttribute>>();logger.LogError(context.Exception, context.Exception.Message);knownException = KnownException.Unknown;context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;}else{knownException = KnownException.FromKnownException(knownException);context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;}context.Result = new JsonResult(knownException){ContentType = "application/json; charset=utf-8"};}}
}

处理逻辑与之前的相同

接着注册 Filters

services.AddMvc(mvcOptions =>
{mvcOptions.Filters.Add<MyExceptionFilter>();
}).AddJsonOptions(jsonoptions =>
{jsonoptions.JsonSerializerOptions.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
});

启动程序,输出如下:

{"message":"未知错误","errorCode":9999,"errorData":null}

输出与之前的一致,因为这是在 Controller 里面输出了错误

如果在 MVC 的中间件之前输出错误的话,它是没办法处理的

这个场景一般情况下是指需要对 Controller 进行特殊的异常处理,而对于中间件整体来讲的话,又要用另一种特殊的逻辑来处理的时候,可以用 ExceptionFilter 的方式处理

这种方式还可以通过 Attribute 的方式

自定义一个 MyExceptionFilterAttribute

namespace ExceptionDemo.Exceptions
{public class MyExceptionFilterAttribute : ExceptionFilterAttribute{public override void OnException(ExceptionContext context){IKnownException knownException = context.Exception as IKnownException;if (knownException == null){var logger = context.HttpContext.RequestServices.GetService<ILogger<MyExceptionFilterAttribute>>();logger.LogError(context.Exception, context.Exception.Message);knownException = KnownException.Unknown;context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;}else{knownException = KnownException.FromKnownException(knownException);context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;}context.Result = new JsonResult(knownException){ContentType = "application/json; charset=utf-8"};}}
}

在 Controller 上面标注 MyExceptionFilter

[MyExceptionFilter]
public class WeatherForecastController : ControllerBase

启动运行之后效果相同

这两种方式的效果是对等的,区别在于说可以更细粒度的对异常处理进行控制,可以指定部分的 Controller 或者 Exception,来决定我们的异常处理,也可以在全局注册 ExceptionFilter

当然因为 ExceptionFilterAttribute 也实现了 IExceptionFilter,所以它也可以注册到全局,也可以把它当作全局异常处理的过滤器来使用,Controller 上面也就不需要标记了

注册 Filters

services.AddMvc(mvcOptions =>
{//mvcOptions.Filters.Add<MyExceptionFilter>();mvcOptions.Filters.Add<MyExceptionFilterAttribute>();
}).AddJsonOptions(jsonoptions =>
{jsonoptions.JsonSerializerOptions.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
});

在 Controller 上面取消标注 MyExceptionFilter

//[MyExceptionFilter]
public class WeatherForecastController : ControllerBase

启动程序,输出结果一致

这个场景对于我们定义一些 API,然后对 API 进行定义我们的异常处理的约定是很有帮助的

总结一下

首先我们需要定义特定的异常类或者接口,我们可以定义抽象类,也可以用接口的方式,例子中是通过接口的方式表示业务逻辑的异常

对于业务逻辑的异常,实际上需要定义全局的错误码

对于未知的异常,应该输出特定的输出信息和错误码,然后记录完整的日志,我们不应该把系统内部的一些比如说异常堆栈这些信息输出给用户

对于已知的业务逻辑的异常,用 Http 200 的方式,对于未知的异常,用 Http 500 的方式,这样可以让监控系统更好的工作

另外一个建议就是尽量记录所有的异常的详细信息,以供后续对日志进行分析,也供监控系统做一些特定的监控警告

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/311151.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2019年第十届蓝桥杯国赛B组试题A-平方序列-枚举

【问题描述】 小明想找到两个正整数 X 和 Y&#xff0c;满足 2019 < X < Y;2019^2 , X^2 , Y^2 组成等差数列。请你求出在所有可能的解中&#xff0c;X Y 的最小值是多少&#xff1f; 答案提交 这是一道结果填空的题&#xff0c;你只需要算出结果后提交即可。 本题的结…

lcd刷新慢_LCD1602刷新率很慢的问题

#include"lcd.h"/******************************************************************************** 函 数 名 : Lcd1602_Delay1ms* 函数功能 : 延时函数&#xff0c;延时1ms********************************************************…

【朝夕技术专刊】Core3.1WebApi_Filter-Authorize详解

欢迎大家阅读《朝夕Net社区技术专刊》第6期我们致力于.NetCore的推广和落地&#xff0c;为更好的帮助大家学习&#xff0c;方便分享干货&#xff0c;特创此刊&#xff01;很高兴你能成为忠实读者&#xff0c;文末福利不要错过哦&#xff01;前言&#xff1a;本部分文档将详细给…

2019年第十届蓝桥杯国赛B组试题D-求值-枚举

【问题描述】 学习了约数后&#xff0c;小明对于约数很好奇&#xff0c;他发现&#xff0c;给定一个正整数 t&#xff0c;总是可以找到含有 t 个约数的整数。 小明对于含有 t 个约数的最小数非常感兴趣&#xff0c;并把它定义为 St 。 例如 S1 1, S2 2, S3 4, S4 6&#…

pythonimport是拷贝_02Python学习笔记之二.一【import、==和is、深浅拷贝】2019-08-17

章节号内容1图片格式(png)宽度大于620px,保持高宽第1章节  import模块1-1 import模块—sys.path↓import导入模块的搜索路径&#xff1a;In [1]: import sysIn [2]: sys.pathOut[2]:#第一个为当前路径[,/usr/lib/python36.zip,/usr/lib/python3.6,/usr/lib/python3.6/lib-dyn…

以正确的方式下载和配置 ASP.NET Core 官方源码

我们可以在Github上面直接查看ASP.NETCore 3.x的源代码&#xff0c;但是我们也可以把源代码下载下来进行查看。而下载源代码进行查看有很多好处&#xff1a;任意的导航源代码内置了一个示例项目直接调试源代码下载源代码想下载并配置好源码&#xff0c;你需要&#xff1a;最新版…

2017年第八届蓝桥杯国赛B组试题A-36进制-进制转换

【问题描述】 对于16进制&#xff0c;我们使用字母A-F来表示10及以上的数字。 如法炮制&#xff0c;一直用到字母Z&#xff0c;就可以表示36进制。 36进制中&#xff0c;A表示10&#xff0c;Z表示35&#xff0c;AA表示370 你能算出 MANY 表示的数字用10进制表示是多少吗?【答…

h5应用 vue 钉钉_uniapp开发一个小视频应用(一)

“uni-app 是一个使用 Vue.js 开发所有前端应用的框架&#xff0c;是一种终极的跨平台解决方案&#xff0c;这里的平台&#xff0c;主要指的是App平台(android、ios)、小程序平台、H5平台。开发者编写一套代码&#xff0c;可发布到iOS、Android、H5、以及各种小程序(微信/支付宝…

Blazor入门

&#xff2e;&#xff2f;&#xff37;现在行动&#xff01;Blazor是一个基于C#&#xff0c; Razor和 HTML的新的Web UI框架。它通过WebAssembly运行在浏览器中。有利于使用C#而不是JavaScript构建交互式的Web UI。这篇文章演示了如何使用Blazor构建SPA应用。Blazor简化了可在任…

第七届蓝桥杯(国赛)——随意组合-dfs,next_permutation

【问题描述】 小明被绑架到X星球的巫师W那里。 其时&#xff0c;W正在玩弄两组数据 (2 3 5 8) 和 (1 4 6 7) 他命令小明从一组数据中分别取数与另一组中的数配对&#xff0c;共配成4对&#xff08;组中的每个数必被用到&#xff09;。 小明的配法是&#xff1a;{(8,7),(5,6),(…

方框加对勾怎么输入_对号“√”怎么输入到方框“□”-空格对号

对号”√”怎么输入到方框”□”内啊&#xff1f;&#xff1f;是这样的&#xff0c;我在做一个表格例如&#xff1a;1&#xff0c;是否完成。□2&#xff0c;是否已经准备好资料。□如果“是”就在方框内打对号“√”&#xff0c;不是就打错号“X”但是怎么打在方框内阿&#x…

C#桌面开发的未来WebWindow

WebWindowWebWindow是跨平台的库。Web Window的当前实验实现可在以下平台上运行&#xff1a;Windows – 需要基于Chromium的EdgeLinux – 使用WebKitMac – 需要Safari源码https://github.com/SteveSandersonMS/WebWindow.gitZeje Fork的分支&#xff1a;https://github.com/ze…

第七届蓝桥杯决赛真题 - 凑平方数-全排列+dfs+set去重

题目&#xff1a; 凑平方数 把0~9这10个数字&#xff0c;分成多个组&#xff0c;每个组恰好是一个平方数&#xff0c;这是能够 办到的。比如&#xff1a;0, 36, 5948721再比如&#xff1a; 1098524736 1, 25, 6390784 0, 4, 289, 15376 等等…注意&#xff0c;0可以作为独立的…

计算标准差分母是n还是n-1?

概述 提问&#xff1a;在我们计算某些数据标准差&#xff08;或者方差&#xff09;的时候&#xff0c;会发现有些公式分母是n&#xff0c;而有些公式的分母却是&#xff08;n-1&#xff09;&#xff0c;那么到底哪个公式才是正确的呢&#xff1f; 答案&#xff1a; 如果是算…

三调 图斑地类面积_三调对于最小上图图斑面积的要求是:

【单选题】设二维数组 A[1...m,1...n] (即 m 行 n 列)按行存储在 B[1...m*n] 中,则二维数组元素 A[i,j] 在一位数组 B 中的下标为( )【单选题】二维数组 a[1..N , 1..N] 可以按行存储或按列存储。对于数组元素 a[i,j] ( 1<i,j<N ),当( )时,在按行和按列两种存储方式下,其…

C#小游戏—钢铁侠VS太空侵略者

身为漫威迷&#xff0c;最近又把《钢铁侠》和《复仇者联盟》系列又重温了一遍&#xff0c;真的是印证了那句话&#xff1a;“读书百遍&#xff0c;其意自现”。看电影一个道理&#xff0c;每看一遍&#xff0c;都有不懂的感受~ 不知道大伙是不是也有同样的感受&#xff0c;对于…

受检异常 非受检异常_这样设计 Java 异常更优雅,赶紧学

来源&#xff1a;Lrwinlrwinx.github.io/2016/04/28/如何优雅的设计java异常/导语异常处理是程序开发中必不可少操作之一&#xff0c;但如何正确优雅的对异常进行处理确是一门学问&#xff0c;笔者根据自己的开发经验来谈一谈我是如何对异常进行处理的。由于本文只作一些经验之…

[蓝桥杯][2018年第九届真题]调手表-bfs

小明买了块高端大气上档次的电子手表&#xff0c;他正准备调时间呢。在 M78 星云&#xff0c;时间的计量单位和地球上不同&#xff0c;M78 星云的一个小时有 n 分钟。大家都知道&#xff0c;手表只有一个按钮可以把当前的数加一。在调分钟的时候&#xff0c;如果当前显示的数是…

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

23 | 静态文件中间件&#xff1a;前后端分离开发合并部署骚操作我们先来看一下静态文件中间件有哪些能力1、支持指定相对路径2、支持目录的浏览3、支持设置默认文档4、支持多目录映射源码链接&#xff1a;https://github.com/witskeeper/geektime/tree/master/samples/StaticFi…

src获取同级目录中的图片_一个简单的Python爬虫实例:百度贴吧页面下载图片

本文主要实现一个简单的爬虫&#xff0c;目的是从一个百度贴吧页面下载图片。1. 概述本文主要实现一个简单的爬虫&#xff0c;目的是从一个百度贴吧页面下载图片。下载图片的步骤如下&#xff1a;获取网页html文本内容&#xff1b;分析html中图片的html标签特征&#xff0c;用正…