柚子Nan--回归原点

Everything can be as easy as you like or as complex as you need.
posts - 231, comments - 970, trackbacks - 17, articles - 29
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

关于异常处理的一点感受

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

   常用的异常就是两大类,一种是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

Feedback

#1楼    回复  引用    

2005-06-09 19:30 by mzl [未注册用户]
不错!

#2楼    回复  引用  查看    

2005-06-10 09:31 by yinh      
winform中呢?有没有研究过怎么样的解决方案较好?似乎也是有个UI异常的处理的。

#3楼 [楼主]   回复  引用  查看    

2005-06-10 19:23 by 柚子Nan      
不大熟悉Winform啊,作了2年的webform了,winform彻底忘记了!

#4楼 [楼主]   回复  引用  查看    

2005-08-04 16:59 by 柚子Nan      
关于Winform看到了一段代码:
Application.ThreadException +=
new ThreadExceptionEventHandler(Application_ThreadException);
AppDomain.CurrentDomain.UnhandledException +=
new System.UnhandledExceptionEventHandler(AppDomain_UnHandledException);

public static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
HandleException(e.Exception, ExPolicy.General);
}

public static void AppDomain_UnHandledException(object sender, System.UnhandledExceptionEventArgs e)
{
if (e.ExceptionObject is System.Exception)
{
HandleException((System.Exception)e.ExceptionObject, ExPolicy.Unhandled);
}
}

#5楼    回复  引用  查看    

2006-09-23 12:54 by 壮志      
好文章

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2005-06-09 13:37 编辑过
 
另存  打印