从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之五全局异常处理
在 上一篇 中讲到了在netcore项目中如何配置nlog将日志存到数据库,这篇中将讲述如何处理自定义抛出的异常以及未处理的异常,并通过日志记录下来。
为什么要进行异常的全局处理和记录日志呢?
在实际的软件项目开发与迭代中,无论程序员是久经沙场的老将,还是初出茅庐的萌新,出现异常(尤其是空指针异常)是必然的,
一般来说,当出现异常且没有处理的情况下,异常会直接抛至运行环境,导致系统崩溃或其它错误,那么如何才能做到系统在运行时遇到错误而不致使系统崩溃呢,需要在系统出现未捕捉的异常时进行全局处理并记录以方便修复!
在程序中,在某些地方可能需要手动抛出异常,需要自定义消息等等,因此,我们先添加自定义异常类 customsystemexception 。
/// <inheritdoc /> /// <summary> /// 自定义系统错误异常 /// </summary> public class customsystemexception : exception { /// <summary> /// http状态码 /// </summary> public int code { get; set; } /// <summary> /// 错误消息 /// </summary> public object[] args { get; set; } public customsystemexception(string message, int code, params object[] args) : base(message) { code = code; args = args; } }
在netcore中有一个 exceptionfilterattribute 的异常过滤属性,可以继承它来重写当触发时的事件。
/// <inheritdoc /> /// <summary> /// 全局异常处理过滤器 /// </summary> public class exceptionfilter : exceptionfilterattribute { public override void onexception(exceptioncontext filtercontext) { if (filtercontext.exceptionhandled) return; var controllername = (string)filtercontext.routedata.values["controller"]; var actionname = (string)filtercontext.routedata.values["action"]; var request = filtercontext.httpcontext.request; loghelper.logger.fatal(filtercontext.exception, $"【异常信息】:{filtercontext.exception.message} 【请求路径】:{request.method}:{request.path}\n " + $"【控制器】:{controllername} - 【方法】:{actionname}\n " + $"【主机地址】:{ demoweb.getclientip()} " + $"【用户代理】:{ request.headers["user-agent"]}");//demoweb为前面章节添加的类 if (filtercontext.exception is customsystemexception se) { filtercontext.result = new customhttpstatuscoderesult(200, se.code, se.message); } else { #if debug console.writeline(filtercontext.exception); var content = filtercontext.exception.tojson();//tojson为静态扩展方法 为前面章节添加的类 #else var content = "系统错误,请稍后再试或联系系统管理人员。"; #endif filtercontext.result = new customhttpstatuscoderesult(200, 500, content);//customhttpstatuscoderesult为自定义返回结果 为前面章节添加的类 } filtercontext.exceptionhandled = true; } }
其中涉及到的在前面章节都有添加,统一返回结果以及静态方法等。
这里添加好了之后,我们需要将这个过滤器注入到mvc中去,在 startup 类中的 configureservices方法 中做如下更改:
services.addmvc(options => { options.filters.add(new exceptionfilter()); }).setcompatibilityversion(compatibilityversion.version_2_1); //用上面的替换下面的 //services.addmvc().setcompatibilityversion(compatibilityversion.version_2_1);
到这里,添加完了全局异常处理,然后在控制器层添加一个测试方法,测试代码如下: ps:若启动访问不到测试接口,请在启动项目中添加该控制器类库的引用!
[route("api/[controller]")] public class exceptiontestcontroller : basecontroller { [httpget] [route("dividezero")] public actionresult testdividezero() { loghelper.logger.debug("测试除0异常"); var zero = 0; var test = 10 / zero; return succeed(); } }
测试效果如下:
个人建议:不要用太多的异常处理,也最好不要进行手动抛出异常处理,能规避的异常和能处理的异常建议都进行处理并返回提示信息,同时要尽量避免使用套嵌异常处理,因为异常处理使用不合理会使系统的性能下降。
在下一篇中将介绍如何使用过滤器来进行模型验证处理,验证请求数据是否符合访问模型设置的要求,并返回错误提示信息。
有需要源码的在下方评论或私信~给我的svn访客账户密码下载,代码未放在github上。
推荐阅读
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之五全局异常处理
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之七使用JWT生成Token(个人见解)
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之十一Swagger使用一
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之十数据库基础方法的封装
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之九如何进行用户权限控制
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之六使用过滤器进行全局请求数据验证
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之八MemoryCache与redis缓存的使用
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之十一Swagger使用一
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之七使用JWT生成Token(个人见解)
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之十二Swagger(参数)使用二