在上一篇中"异常处理--Exception(一)"中,跟大家简单介绍了一下Exception,也使大家充分的了解了Exception管理在一个项目中的重要性,那如何在我们的项目中处理异常呢?因为我从事的是Web开发,所以我只跟大家讨论Web的解决方案,Win的解决方式,还希望同大家一起探讨。

上一章中我们了解了异常发生的原因,同时也说了不存在没有bug的程序,任何网站都会遇到各种各样的问题,无论是大网站还是小网站都会存在,但大公司和小公司对待异常的态度全然不同,一个是主动出击,一个是守株待兔,我们是好的开发者,我们不能坐以待毙,我们必须主动出击。好了,废话少说,切入主题。

现在网站一般都采用多层开发,多层开发的时候,我们应该在哪里处理异常、在抛出异常呢?微软的意见是类库的开发人员尽量不要处理异常,类库的编写应该按照正常的逻辑去编写,当然也有例外,注意事项可以参见"设计异常解决方案的几点注意事项",好的,按照规范,我们应该尽量在高层进行捕捉和处理,那我们该怎么捕捉,捕捉后怎么处理,捕捉哪些异常呢?虽然微软提供了很多系统异常,但是这些异常只是负责抛出相关的信息,并没有为记录下来,或者出现高级异常的时候,及时通知我们,这样的做法还是守株待兔,我们还是应该主动的对其进行处理。好在微软让我们可以自由的创建自定义的Exception,最好是设定一个自定义Exception基类,让你的其他自定义Exception都继承这个类,以便今后更好的扩展。抛出异常其实是性能消耗很大的操作,但是Richer教父说过,抛出异常的性能和你程序的稳定性相比,就变得非常渺小了。所以我们还是偏向于稳定性。因为处理异常的性能消耗,只是在异常发生时才产生,所以性能方面的问题,我们可以忽略了。(或许这话比较拗口,但相比系统的性能,我更趋向于系统的稳定)

如何创建一个自定义的Exception?

不得不说微软考虑的太周到了,要创建一个自定义的Exception是非常简单的。打开VS,创建一个项目,然后添加一个类,在namespace范围内,输入Exception,然后2下Tab,VS就自定帮您创建一个自定义的Exception了。Exception的相关属性和方法,可以参见MSDN。不过自动创建的Exception都是继承System.Exception的,按照微软当初的设想,自定义的异常应该继承System.ApplicationException (可笑的是,微软自己都没有遵守这个约定)。我们设定这个作为我们的Exception基类MyBaseException。

代码片断:

[global::System.Serializable]

public class MyBaseException : ApplicationException

{

public MyBaseException() { }

public MyBaseException(string message) : base(message) { }

public MyBaseException(string message, Exception inner) : base(message, inner) { }

protected MyBaseException(

System.Runtime.Serialization.SerializationInfo info,

System.Runtime.Serialization.StreamingContext context)

: base(info, context) { }

}

这就是一个标准的自定义Exception了,至于其它的自定义Exception,应该根据你的项目来进行相关的定义。

在进行其他定义之前,我们先来想想,我们捕捉这些Exception之后我们需要做些什么?我们需要知道异常发生的各种信息,所以我们需要Log。Log能方便的让我们查阅发生的异常及Log的异常信息。Log有很多方式,大概的有以下几种:

文本记录

数据库记录

系统事件记录(Trace)

第三方组件(Log4Net)

这几种方式各有利弊,可以根据项目的需求进行选择,当然你也可以几种方式合用,比如我们默认的是文本记录方式,但是在创建Log时发生了System.IOException时,我们就必须选择其他的方式进行Log。

Log方式

便捷性

查阅性

安全性

结合性

文本记录

方便

一般

数据库记录

一般

方便

一般

系统事件记录

复杂

复杂

一般

第三方组件

复杂

一般

一般

我列举了几种方式的利弊,大家可以有条件的选择。如果你的项目中已经使用第三方组件记录方式,那我建议您使用它。在我后面的解决方案中,我会利用前2种比较常见的方式相结合。

Log的目的是为我们开发者提供发生异常的时间、地点、人物、原因,所以我们必须尽可能的详细地记录,根据一个Exception获取信息的方法:

Data

Source

Dates and Times

DateTime.Now

Source of Exception

Exception.Source

Type of Exception

Object.GetType

Exception Message

Exception.Message

Current Method

Reflection.MethodInfo.GetCurrentMethod

Machine Name

Environment.MachineName or Dns.GetHostName

CurrentIP

Dns.GetHostByName("host").AddressList[0].Address

Call Stack

Exception.StackTrace or Environment.StackTrace

OS Information

Environment.OSVersion

Applcation Domain

AppDomain.FriendlyName

Current Assembly

Reflection.Assembly.GetExecutingAssembly

Root Error Cause

Exception.GetBaseException

Chained Exception

Exception.InnerException

Assembly Version

Included in AssemblyName.FullName

Thread ID

AppDomain.GetCurrentThreadId

Thread User

Threading.Thread.CurrentPrincipal

我们可以根据上面的表格,构建我们自己所需要的Log信息。为了便捷的管理,我们应该采用同一格式,进行Log。这里贴一个我写的信息格式,以供参考:

public static class ExceptionLogFormatHelper

{

public static string ExceptionLogFormatter(Exception ex)

{

StringBuilder sbLog = new StringBuilder("\r\n------------------------------------\r\n");

Exception ochainException = ex;

var currentExceptionIndex = 1;

while (ochainException != null)

{

sbLog.Append("\r\nException " + currentExceptionIndex + " )")

.Append("\r\nException Type:" + ochainException.GetType().FullName)

.Append("\r\nException Source:" + ochainException.Source)

.Append("\r\nException Message:" + ochainException.Message)

.Append("\r\nException Date:" + DateTime.Now)

.Append("\r\nEnvironment Stack:" + System.Environment.StackTrace);

ochainException = ochainException.InnerException;

currentExceptionIndex++;

}

sbLog.Append("\r\n------------------------------------\r\n");

return sbLog.ToString();

}

}

你也可以根据你自己想要的信息构建这么一个方法。

这一篇废话多了点,不过还是有必要了解下。还介绍了自定义异常的创建,日志方式的对比,在下一篇,我将介绍通知、异常处理流程和定义自己的一个MyBaseException。

==

异常处理—Exception(二)的更多相关文章

  1. .NET MVC全局异常处理(二)

    目录 .NET MVC全局异常处理(二) MVC过滤器Filter .NET MVC全局异常处理(二) 对上节的内容进行了补充 MVC过滤器Filter MVC有四种过滤器:Authorization ...

  2. 异常处理—Exception(三)

    最近有点事,把这个系列给落下了,给大家道个歉,这里还要感谢我的老婆,谢谢她一直对我的支持:) 系列回顾: 1.异常处理--Exception(一) 2.异常处理—Exception(二) 上一篇中主要 ...

  3. 异常处理 Exception

    一.异常类 1.在C#中所有的异常都是使用一个异常类型的示例对象表示的,这些异常类型都是继承自System.Exception类型,或者直接使用System.Exception类型的实例对象: 2.在 ...

  4. 3.后台配置、环境变量、日志、异常处理、二次封装Response、路由组件

    目录 环境变量 封装logger 封装项目异常处理 二次封装Response模块 路由组件配置 环境变量 dev.py # 环境变量操作:小luffyapiBASE_DIR与apps文件夹都要添加到环 ...

  5. ORACLE PL/SQL异常处理(Exception)学习笔记

    1.PL/SQL错误类型 错误类型 报告者 处理方法 编译时错误 PL/SQL编译器 交互式地处理:编译器报告错误,你必须更正这些错误 运行时错误 PL/SQL运行时引擎 程序化地处理:异常由异常处理 ...

  6. Akka(26): Stream:异常处理-Exception handling

    akka-stream是基于Actor模式的,所以也继承了Actor模式的“坚韧性(resilient)”特点,在任何异常情况下都有某种整体统一的异常处理策略和具体实施方式.在akka-stream的 ...

  7. Web应用的统一异常处理(二十四)

    我们在做Web应用的时候,请求处理过程中发生错误是非常常见的情况.Spring Boot提供了一个默认的映射:/error,当处理中抛出异常之后,会转到该请求中处理,并且该请求有一个全局的错误页面用来 ...

  8. .NET中的异常处理机制(二)

    本文我们继续通过另一个例子来讲解在C#中如何捕捉异常并进行处理. 首先,我们新建一个控制台应用和一个Class Library Project.如下图所示. 图1 ConsoleUI应用 图2 Exc ...

  9. java异常处理Exception

    我看别人的面经中有一道题目就问到了Exception,即java的异常处理的,我曾经也学了java的异常处理,可是我查了下,看了别人的博客关于写的exception异常处理.我发现,自己学的不坚固,仅 ...

随机推荐

  1. Android----Material Design之(FloatActionButton,CoordinatorLayout,CollapsingToolbarLayout,AppBarLayout,TabLayout等)

    Material Design 的一些UI 平常开发还是用的比较多的,以前没写,最近总结一下,写一篇博客,要求版本在5.0以上. 主要介绍了FloatActionButton,CoordinatorL ...

  2. iptables详解(11):iptables之网络防火墙

    我们一起来回顾一下之前的知识,在第一篇介绍iptables的文章中,我们就描述过防火墙的概念,我们说过,防火墙从逻辑上讲,可以分为主机防火墙与网络防火墙. 主机防火墙:针对于单个主机进行防护. 网络防 ...

  3. 浅谈js数据类型识别方法

    js有6种基本数据类型  Undefined , Null , Boolean , Number , String ,Symbol和一种引用类型Object,下面我们就来一一看穿,哦不,识别他们. t ...

  4. Django开发BUG "Model class WH_auth.models.User doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS."

    当进行数据库迁移的时候发生问题,报错如下:RuntimeError: Model class WH_auth.models.User doesn't declare an explicit app_l ...

  5. python:小乌龟turtle

    turtle的意思是乌龟,也是python中自带的图形函数,使用turtle的方法也很形象,就好像在画布上有一个小乌龟(在画布上是一个箭头),然后你可以让它动来动去,它经过的地方就被留下了记号. 例如 ...

  6. rsync的配置文件模板及简单介绍,命令及参数

    必须知道推送有一个限速参数.--bwlimit=100 工作总必须要加.有三种模式,1.本地的模拟cp命令,在一个服务器2.远程的两个服务器之间,模拟scp3.以socket进程监听的方式启动rsyn ...

  7. C++STL内存配置的设计思想与关键源码分析

    说明:我认为要读懂STL中allocator部分的源码,并汲取它的思想,至少以下几点知识你要了解:operator new和operator delete.handler函数以及一点模板知识.否则,下 ...

  8. 经典问题:查询有多少段区间和等于k值

    题目连接 题意:在大小为1e5以内的数组求存在多少个区间和的值等于k的次方 这种题很经常见,总是想着用两个for循环解决,但是一定会超时. 题解:算出前缀和,使用map去查找mp[sum[i+1]-t ...

  9. Xss测试

    <Script>alert(“XSS attack available!”);</Script>

  10. Popular HashMap and ConcurrentHashMap Interview Questions

    http://howtodoinjava.com/core-java/collections/popular-hashmap-and-concurrenthashmap-interview-quest ...