如何重构使用一般的Exception?

时间:2010-04-20 05:54:48

标签: c# .net exception-handling

我们的代码随处可见一般情况。

通常它会将错误写入数据库中的日志表,并向用户显示一个MessageBox,表示请求的操作失败。如果存在数据库交互,则回滚事务。

我已经引入了业务逻辑层和数据访问层来解开一些逻辑。在数据访问层中,我选择不捕获任何内容,并且还抛出ArgumentNullExceptions和ArgumentOutOfRangeExceptions,以便从堆栈传递的消息不会直接来自数据库。

在业务逻辑层我放了一个try catch。在catch我回滚事务,做 伐木和重新抛出。

在表示层中,还有另一个显示MessageBox的try catch。

我现在正在考虑捕获DataException和ArgumentException而不是Exception,我知道代码只访问数据库。

在代码访问Web服务的地方,我想我会创建自己的“WebServiceException”,只要抛出HttpException,WebException或SoapException,就会在数据访问层中创建它。

所以现在,一般来说,我会抓住2或3个例外,目前我只抓住一般的例外,我觉得这对我来说似乎没问题。是否有人再次包装异常以将消息传递到表示层?

我想我应该向Main()添加一个try catch来捕获Exception,尝试记录它,显示“Application遇到错误”消息并退出应用程序。 所以,我的问题是,有没有人在我的计划中看到任何漏洞?是否有任何明显的异常,我应该抓住或做这些几乎覆盖它(除了文件访问 - 我认为只有一个地方我们读写配置文件)。

2 个答案:

答案 0 :(得分:2)

好像您正在对您的应用程序进行一些改进。我通常还会在try/catch Exception块中包装应用程序的最外层,以便意外的异常(例如运行时的异常)可以允许应用程序正常退出。

有一个问题是,如果将业务逻辑委托给数据回滚,则是否有意义。这似乎更好地封装在数据访问层中。然后,您可以从数据层中抛出您选择的异常,而不是打开该层以抛出任何旧异常,因为如果您的数据层抛出了您不期望的内容,业务逻辑层会发生什么?

或者,如果您以后提取数据访问层并将其替换为其他内容,该怎么办?至少,您必须从业务逻辑层中删除所有回滚逻辑。

答案 1 :(得分:2)

我会使用try / finally(或者等效的using语句)进行回滚,而不是在catch块中进行。特别是如果您只捕获特定的异常,如果抛出意外的异常类型,您仍然希望发生数据库回滚。

除了少数例外,我很少使用捕获,除了:

  • 在物理层边界,我在catch块中使用try / catch和log / throw,以便可以在服务器上记录异常。使用较新的技术(例如WCF)可以在没有try / catch的情况下记录异常(例如,使用WCF DispatchBehavior)。

  • 在表示层中的顶级处理程序中。

在业务和数据层中,会有很多try / finally(即使用语句),但几乎从不捕获。