自建工具集开发文档------异常处理(1.0.0.1)

类别:.NET开发 点击:0 评论:0 推荐:

自建工具集开发文档------异常处理(1.0.0.1

 

 

版本号

创建人

创建时间

备注

1.0.0.1

穆仕途

2003-12-20

草稿

 

 

关键字C#、工具集、异常、错误

正文

 

       .Net Framework提供了完整、功能强大的异常处理机制,在此写这个异常处理类的主要目的是为了把异常集中处理,并记录日志,方便于测试和维护。并且可以把它放到别的系统中而不需要做程序上的改动,只需要修改部分配置信息而已。

 

设计目标

 

1.     使用自定义的异常消息来给出用户提示和异常信息。

2.     尽量简化对异常类调用的复杂度。

3.     精确定位异常发生的位置。

 

.Net Framework的异常处理机制(此部分内容摘自.Net帮助文档

 

C# 中的异常提供了一个处理系统级和应用程序级错误状态的结构化的、统一的和类型安全的方法。所有的异常必须由从 System.Exception 派生的类类型的实例表示。发生异常时,系统将搜索可以处理该异常的最近的 catch 子句,而这是由异常的运行时类型确定的。首先,搜索当前的方法以查找一个词法上封闭的 try 语句,并按顺序考虑与该 try 语句相关联的 catch 子句。如果上述操作失败,则搜索调用当前方法的方法以查找一个词法上封闭的 try 语句,它封闭当前方法调用的场所。此搜索将一直进行下去,直到找到可以处理当前异常的 catch 子句(通过指定与被引发的异常的运行时类型属于同一个类或基类的异常类)。不指定异常类的 catch 子句可以处理任何异常。

找到匹配的 catch 子句后,系统将把控制转移到该 catch 子句的第一条语句。在 catch 子句的执行开始前,系统将首先按顺序执行任何与嵌套程度大于捕捉到该异常的 try 语句的 try 语句相关联的 finally 子句。

如果没有找到匹配的 catch 子句,则发生下列两种情况之一:

              如果对匹配的 catch 子句的搜索到达静态构造函数或静态字段初始值设定项,则在触发该静态构造函数的调用的场所引发 System.TypeInitializationExceptionSystem.TypeInitializationException 的内部异常包含最初引发的异常。

              如果对匹配的 catch 子句的搜索到达最初启动该线程的代码,则将终止线程的执行。此类终止的影响是由实现定义的。

特别值得注意的是在析构函数执行过程中发生的异常。如果在析构函数执行过程中发生异常且该异常未被捕获,则将终止该析构函数的执行,并调用基类的析构函数(如果有)。如果没有基类(如 System.Object 中的情况),或者如果没有基类析构函数,则该异常将被放弃。

 

设计思想:

 

系统设计和运行中会遇到两种异常,一种是由系统运行时抛出的异常,这是依赖于.Net Framework,可以通过try块来捕获,比如数据库打开连接;另一种是自定义的异常,比如说输入数据格式错误所引发的异常,或许只应该说成是错误吧。

 

处理时:

1.       try块来捕获系统可能引发的异常,转换为自己的异常后抛出,不做别的处理;

2.       需要引发异常的地方,实例化一个自己的异常后抛出,不做别的处理;

3.       一般情况下,所有中间的处理过程皆不对下层抛出的异常做任何处理,也不捕获;

4.       最上层,即直接和界面交互的一层,捕获所有的异常,所有下层抛出的异常,只需要从异常中取出给用户显示的消息即可,在这个层次系统引发的异常,按第一条进行处理。

 

下面给出所有的实现细节:

 

异常信息配置文件

 

异常信息存放于XML文件exceptionconfig.xml中,文件格式如下所示:

 

<?xml version="1.0" encoding="utf-8" ?>

<ExceptionConfig>

     <Exception id="1" name="ERROR_WRONG_DATA_TYPE" userMsg="数据错误" logMsg="数据类型或者长度错误" level="3"></Exception>

     <Exception id="2" name="ERROR_COMMAND_TYPE" userMsg="程序错误" logMsg="数据库命令类型不正确,只能是procedure或者command" level="5"></Exception>

     <Exception id="3" name="ERROR_BAD_COMMAND_NAME" userMsg="程序错误" logMsg="数据库命令再数据模型文件datamodel.xml中不存在" level="5"></Exception>

     <Exception id="4" name="ERROR_NO_VALID_CONNECTION" userMsg="程序错误" logMsg="连接池没有数据库连接" level="5"></Exception>

     <Exception id="999" name="ERROR_DEFAULT_ERROR" userMsg="程序发生错误错误(用户可见)" logMsg="发生未定义的错误" level="3"></Exception>

</ExceptionConfig>                                 

 

 

文件说明:

 

根接点名称:ExceptionConfig,请注意大小写;

每一个Exception接点对应一条异常信息,各字段的意义如下:

     id:异常的编号,用于文件内标识异常,在给用户显示错误信息的时候也将显示此错误号,从1开始编号,999是一个自定义默认异常信息,不能修改这个结点。

     name:异常的名称,用于编码中引用异常,所以在此文件中,每个异常的名称不能重复,否则取最前面的异常,后面的结点将被覆盖。命名规则建议:以ERROR开始,用下划线分割各个单词,从名字上可以看出异常的大致意思。

     userMsg:用户消息,发生异常的时候,将给用户直接显示此信息。

     logMsg:日志消息,发生异常的时候,将记录到日志文件的信息,尽量描述清楚。

     level:异常的等级,标志异常的严重性,取值从15(包括15),严重性越高值越大。

 

异常类说明

 

字段:

 

     private string exceptionName = null;

     private int exceptionNo = 0;

     private Constant.ExceptionLevel exceptionLevel;

     private string userMsg = null;

 private string logMsg = null;

 

 

   exceptionName:异常的名称,和XML文件中的name相对应。

   exceptionNo:异常的编号,用于显示给终端用户,和XML文件中的id相对应。

   exceptionLevel:异常的等级,枚举型,在常量中有定义,取值从15,对应于XML文件中的level字段。

   userMsg:用户消息,和XML文件中的userMsg相对应。

   logMsg:日志消息,和XML文件中的logMsg相对应。

 

属性:

 

public string UserMsg{get, set}

public string LogMsg{get, set}

 

公共构造器:

 

public utilException(){}

public utilException(string _userMessage, string _logMessage, Constant.ExceptionLevel _exceptionLevel) {}

public utilException(string _exceptionName) {}

public utilException(System.Exception e, string _userMsg) {}

 

   _exceptionName:异常的名称,和XML文件中的name相对应,构造器将通过这个字段从XML文件中获取错误描述信息来初始化异常类的各个字段。

   可以在程序中提供异常的用户消息、日志消息、等级来初始化异常,但是不提倡这样,将给维护带来困难。

   尽量使用System.Exception来实例化自己的异常类,这样可以自动把堆栈信息记录到日志中。

   可以用异常的名称来初始化异常,构造器从XML文件中获取异常信息。

 

方法说明:

 

private void WriteLog()

private string GetLogMsg()

private string GetExceptionClass()

private string GetInnerMessage()

 

程序中所有的方法都是私有的,在构造器中,将调用WriteLog()来书写日志,其中方法GetExceptionClass()用于获取InnerException中的堆栈信息,GetInnerMessage()用于获取InnerException中的错误信息,对于自己初始化的异常类返回空。

 

存在的问题:

 

   自己初始化的异常类,无法从中获取引发异常时的堆栈信息,只有用系统引发的异常来初始化自己的异常类的时候可以获取异常时的堆栈信息。

   异常等级的设定,当初的想法是根据错误的不同等级来做相应的处理,甚至根据等级的不同,运行时配置写日志功能的开关。

 

结束语:

 

        我只是实现了很简单的功能,写在这里的介绍也很粗略,没有附带内部详细的实现细节,有对源码感兴趣的朋友可以给我发信[email protected],首先介绍这个类的目的是为了在后面的实现中将会用到这个类。

 

        这样的实现肯定让大家大失所望,这也是闭门造车的结果,希望各位朋友看了以后能给我些改进的意见,万分感谢,我将不断完善,继续努力。

 

 

本文地址:http://com.8s8s.com/it/it45200.htm