柚子Nan--回归原点

Everything can be as easy as you like or as complex as you need.
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

关于异常处理的一点感受

Posted on 2005-06-09 13:35  柚子Nan  阅读(3182)  评论(5编辑  收藏  举报
   由于最近负责项目的异常处理模块,计划把整个项目中的异常重新规划一下,查询了一些资料,有些是夷所思提供,非常感谢! 

   常用的异常就是两大类,一种是SystemException预定义的公共语言运行库异常类的基类,另外就是ApplicationException用户定义的应用程序异常类型的基类。 

   在设计异常的时候,有很多疑惑,其中最我感觉明显的是,我设计的异常如何被触发,如何被捕捉?
答案很简单,分三步(哈哈,跟如何把大象装进冰箱有点像):
1、定义自己的异常类,一般实现四个构造函数,并且把异常类标注为可序列化[Serializable]
还有一点注意的是,您的自定义异常继承自ApplicationException,而不是直接从Exception, 这个是微软推荐的,具体为什么可以参考文档
2、在程序的业务逻辑代码中,知道哪里会出错的地方抛出这个异常。
3、在表现层把这个异常捕捉到,并给客户一定的友好反馈信息。 

如果你自己不抛出,那么自己定义的异常永远都捕捉不到!

   在我们的项目中,用到了很多
try/catch(Exception),根据工具Fxcop的检测结果,不推荐直接catch(Exception)throw Exception,必须使用自己定义的xxxxException类。但是这样就会导致一些无法捕捉到的异常被漏出去,因为我们不能确定它们会在什么地方出现,例如像NullPointerExceptionClassCastExceptionIndexOutOfBoundsException这些RuntimeException,我们可以在所有它们有可能发生的地方去捕获它们,但这确实是很坏的解决方案。但是又不能不处理,把程序的错误页面、核心代码暴露给用户是非常不好的做法! 后来找到了一个比较好的方案,仅对于ASP.NET解决方案有效,在web.config文件中定义<customErrors mode="On" defaultRedirect="CustomerErrorPage.aspx" />

   关于这个
mode,有三个值
on :如果有未捕捉的异常,就直接调到错误页面,一般用在项目、产品发布以后。
off: 用户可以看到所谓的黄页,而不是跳转到错误页面,用在项目开发中。
remoteonly:本机运行的用户可以看到错误页面,而远端的任何用户都是调到错误页面。

   即使有这三个选择,毕竟系统还出错了,那么我们一定想知道错误是什么吧。这就用到了Log的功能,对于何时处理这些异常,如何纪录,也有很多种方案,这里介绍两种。
第一,在每个页面,增加    this.Page.Error +=new EventHandler(Page_Error);然后再事件 Page_Error中处理并纪录异常。很显然,如果页面很多,代价将会很大。
第二,在Global.asax.cs中的方法Application_Error作统一处理,这里就要知道是什么错误引发的了,不要再自己造一套把错误传递的机制了,呵呵,不用担心微软已经帮你做好了,只要一句话,就知道是什么错误引发的错误了。
  Exception lastException = Server.GetLastError();
然后把这个lastException 纪录到Log中就搞定了。

   最后还有一个文章推荐,Best Practices for Handling Exceptions