专栏首页NetCore一个让人遗忘的角落—Exception(三)

一个让人遗忘的角落—Exception(三)

最近有点事,把这个系列给落下了,给大家道个歉,这里还要感谢我的老婆,谢谢她一直对我的支持:)

系列回顾:

1.一个被人遗忘的角落—Exception(一) 2.一个被人遗忘的角落—Exception(二)

上一篇中主要介绍了Log的几种方式,接下来说说通知的方式:

通知方式

说明

Email

这是最常见也是最方便的一种通知方式。 优点:使用简单 缺点:需要依赖于SMTP服务器等

SMS

这也是目前比较流行的通知方式,不过一般不会把所有信息都通过短信进行发送,可以选几个比较关键的Exception进行SMS通知。 缺点:字数、网关、接口等限制。 优点:及时性

Post

通过某种服务,对客户端进行Post Exception。 优点:及时性(不过依赖于客户端) 缺点:需要编写安全的客户端程序。

Get

跟Post优点类似,但需要把Exception先存到某个地方,然后Get的时候获取。

Other

还有很多通知的方式,这个取决于大家的需求了。

一般我们常用的是前2种方式,因为编写还算简单,SMS的接口现在也有很多了。

注:如果在你的程序种有Email发送程序的话,我建议您还是不要使用相同的配置进行发送,建议重新建立一个新的配置,包括发送方式都使用一个新的方法。

这里值得注意的是,当你的Email通知方式抛出异常时,请一定要使用另外一种方式进行通知,因为此时可能你的网站已经发生了不可忽视的异常了。

通知的信息内容比较简单,如果是Email发送方式,就可以使用Log的Log信息进行发送,如果SMS的话,你可以使用模板,或者固定格式进行发送。

通知的内容不是很多,下面来讨论一下 Try / Catch

这个问题本来先前就想说的,前几天也看到杨兄弟的“请讨论try...catch..写在不同地方,有何利害? ”其中讨论的非常激励,很多人说的都比较正确,使我觉得或许我的方案不是最好的,但我决定还是把我的看法写出来,这样才能大家一起来进行讨论。老赵说在内部类的时候最好也能把异常捕捉后,进行封装然后再抛出,不过我个人觉得,如果是类库的话,还是不要去Catch,这是为什么呢?

我认为,类库中的方法是我们程序的最小单元,它的存在是为了我们高层的调用,它的存在必有它的意义,就算它内部调用其他类库的方法(大多会调用FCL),我们最好不要去Catch掉,不过某些时候你可能要违反这个规则,但请记住,封装好你的异常,然后Throw到高层,那样才能不遗漏你的程序发生的Exception。类库中的方法,如果会调用很多其他类库的方法时,你应该考虑你的这个类库或许已经存在了几种可能性改变你的结果了,你该好好的重新设计你的方法。

现在说说我的观点,一般我们的网站会使用三层架构,不过为了解除业务逻辑与页面层的耦合,我们会借助某些模式,以降低它的耦合度。(自己的想法,或许某些概念会错误)

我们的网站大多是对数据库的I、U、D、S的操作,所以数据层基本已经属于了底层类库,业务层进行调用,UI层进行显示信息。(那我们是不是对数据层的异常不进行处理呢?也不一定,如果按照我先前说的,最好是不要在底层进行处理,没有错,但我们不能太绝对,还是根据你的项目来分析后进行安排吧。)

有人会说在数据层,我们会使用ADO等方法,会与数据库进行一定的联系,其中就会抛出各种异常,难道我们不要去处理吗?是的,如果可能,请不要在这里进行处理,我的方案是,去业务层进行捕捉和处理。

业务层我们是不是去把所有异常都处理了呢?请不要这样设想,因为有些异常不是你能全部处理的,我们应该把我们能预知的,我们需要的异常进行处理(姑且把我们的处理程序定义为ExceptionManager)丢到ExceptionManager中进行处理。但我们有时需要抛出一些Exception Message给用户,所以这些异常,请封装好,继续往高层Throw,这时,请不要把异常丢到ExceptionManager中,因为后面我们会有其他地方进行处理的。

到此,轮到我们的UI层了,UI层直接面对的是用户,在我们先前说的,我们必须记录下我们的异常,让后给用户呈现一个友好的用户界面,那样才是做网站的王道。在web.config中,可以设置发生错误时所呈现的一个页面Url,虽然这么做可以给用户一个好的友好界面,但有时,我们需要给用户提供更多的信息,比如请输入用户名等,这时候config配置的页面就无法达到我们的要求了,那我们该如何来做呢?

其实很简单,使用一个HttpModule就可以了,在这个Module中不要牵涉到其他任何东西,因为在Asp.Net中,一个请求的顺序会把你所有的Module都会执行一次,所以不必担心.Net会遗漏,我们只需要配置好就可以了。那我们这个Module只要做哪些工作呢?只需要处理未处理的异常,首先看一段代码:

 1 public class ExceptionHandlingModule : IHttpModule
 2    {
 3        #region IHttpModule 成员
 4
 5        public void Dispose()
 6        {
 7
 8        }
 9
10        public void Init(HttpApplication context)
11        {
12            context.Error += new EventHandler(context_Error);
13        }
14
15        void context_Error(object sender, EventArgs e)
16        {
17            var application = (HttpApplication)sender;
18
19            //获取当前请求的前一个错误
20            //这里的GetLastError 其实是一个封装好的Exception
21            //我们如果想要知道真正的Exception的话,需要用InnerException属性获取。
22            var unHandlingException = application.Context.Server.GetLastError();
23            if (unHandlingException != null)
24            {
25                unHandlingException = unHandlingException.InnerException;
26                if (unHandlingException != null)
27                {
28                    ExceptionManager.HandlingException(unHandlingException);
29
30                    //好了,我们已经把unHandlingException处理了,后面就清除吧
31                    application.Context.ClearError();
32
33                    //当然,如果你想要用户看到错误提示信息的话,记得把Message保留下来
34                }
35            }
36        }
37
38        #endregion
39    }

第三篇就说到这里吧,接下来后面将会把自定义异常、处理的代码给大家说明一下。

其实很多内容都是经过修改了,原先的想法在我写博客的时候,感觉越来越不对劲,看来我还得加把劲,有些地方或许说的不是很合理,也希望大家能给我提出建议,以免误导其他读者:)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一个让人遗忘的角落—Exception(二)

    在上一篇中"一个被人遗忘的角落--Exception(一)"中,跟大家简单介绍了一下Exception,也使大家充分的了解了Exception管理在一个项目中的...

    脑洞的蜂蜜
  • 一个让人遗忘的角落--Exception(一)

    很诱人的标题,今天不是给大家介绍,而是跟大家讨论些问题。 在做开发的这几年中,大大小小的项目也经历了很多,但无论那个项目中,都没有真正的对Exception进...

    脑洞的蜂蜜
  • Catalog Service - 解析微软微服务架构eShopOnContainers(三)

    上一篇我们说了Identity Service,因为其基于IdentityServer4开发的,所以知识点不是很多,今天我们来看下Catalog Service...

    脑洞的蜂蜜
  • python获取栅格点和面值的实现

    以上这篇python获取栅格点和面值的实现就是小编分享给大家的全部内容了,希望能给大家一个参考。

    砸漏
  • Spring RestTemplate 下载大文件

    RestTemplate 是 Spring 3 中引入的同步阻塞式 HTTP 客户端。根据 Spring 官方文档 介绍,在将来的版本中它可能会被弃用,因为他们...

    JAVA葵花宝典
  • 如何通过网站获取航班信息及价格?

    在我们平时有时候需要从一些网站获取一定的价格做参考。我们以空运报价网飞啊网来说,很多公司会通过此网站进行一些市场价格的参考,虽然有时候上网站查询也比较方便,但是...

    逍遥之
  • 最Cool Kubernetes网络方案Cilium入门教程

    现代数据中心的应用系统已经逐渐转向基于微服务架构的开发体系,一个微服务架构的应用系统是由多个小的独立的服务组成,它们之间通过轻量通信协议如HTTP、gRPC、K...

    nevermosby
  • 像素墨镜,大烟卷—Thug Life风格自动生成项目

    AiTechYun 编辑:nanan ? 暴徒生活(Thug Life)是一款非常火热的P图特效,通过加上此特效会让用户的视频或者照片变的非常有趣好玩。其拥有大...

    AiTechYun
  • Android网络 | Socket(Eclipse--Java)

    在获取时使用方法readFromClient()来读取客户端数据。 如果读取数据过程中捕获到 IOException异常, 则说明此Socket对应的客户端...

    凌川江雪
  • [javaSE] 网络编程(TCP-并发上传图片)

    获取Socket对象,new出来,构造参数:String的服务端ip,int的端口号

    陶士涵

扫码关注云+社区

领取腾讯云代金券