我们正在审查该公司的一个系统的例外处理,并发现一些有趣的事情。

大多数代码(如果不是全部)内的一个尝试/抓块,里面抓住框新BaseApplicationException是被扔-这似乎是来自企业图书馆。我现在有点麻烦,因为我看不到的好处关闭这样做。(扔另一个例外随时发生) 一个开发者已经使用的系统的话说就是因为这类负责发布的例外(发送电子邮件和类似的东西),但他并不太确定。在花费一些时间,通过代码我相当有信心说,这就是它所做的是收集有关环境的信息和出版。

我的问题是:-这是合理的包装所有的代码里面试{}捉住{}块和比扔个新的例外?如果是,为什么?有什么好处?

我个人的意见是,它会更容易使用HttpModule,签署了错误的事件应用程序的事件,并做必要的内部模块。如果我们走这条路,将我们错过了什么?任何缺点?

你的意见的非常赞赏。

有帮助吗?

解决方案

从来没有1 catch (Exception ex).周期2.有没有办法可以处理所有不同种类的错误,你可以赶上。

从来没有3 抓住一个例外来源的类型,如果你不能处理它或提供额外的信息(可以用随后的例外处理程序).显示错误信息 处理 错误。

几个原因,从我的头顶:

  • 赶和重新引发昂贵
  • 你会最终失去了堆栈
  • 你就会有一个低信噪声的比例在你的代码

如果你知道如何处理 具体 异常(和重申以前的错误态),抓住它。(这就是为什么它被称为 异常 处理.)

处理异常不是被抓住,听取适当的活动。当做它,你只需要倾听 System.AppDomain.CurrentDomain.UnhandledException, 如果你这样做 Threading - System.Windows.Forms.Application.ThreadException. 对于网络的应用程序,也有类似的机制(System.Web.HttpApplication.Error).

作为包裹框架的例外情况在应用程序(非)具体的例外情况(即 throw new MyBaseException(ex);):完全没有意义的,和一个糟糕的味道。4


编辑

1 从来没有 是一个非常苛刻的字,特别是当它涉及到工程,如@克里斯指出的评论意见。我会承认在高原则,当我第一写这个的答案。

2,3 看看 1.

4 如果你不带来任何新的东西来表,我仍然站在这个。如果你已经抓住了 Exception ex 作为一部分的一个方法你知道可能会失败,任何数量的方式,我认为,目前的方法应该反映在它的签名。和如你所知,例外情况是不一部分的方法的签名。

其他提示

如果我正确地阅读了这个问题,我会说实现一个拦截异常的try / catch(你没有提到 - 它是捕获所有异常,还是只捕获一个特定的异常?)并抛出一个不同的异常通常一件坏事。

缺点:

至少你会丢失堆栈跟踪信息 - 你将看到的堆栈只会扩展到抛出新异常的方法 - 你可能会丢失一些好的调试信息。

如果您正在捕获异常,那么您将冒着屏蔽关键异常的风险,例如OutOfMemory或StackOverflow具有不太严重的异常,从而使进程保持运行,可能它应该被拆除。

可能的优点:

在一些非常特殊的情况下,您可以获取一个没有太多调试值的异常(比如从数据库返回的一些异常)并使用异常包装,这会添加更多上下文,例如您正在处理的对象的id

然而,在几乎所有情况下,这都是难闻的气味,应谨慎使用。

一般情况下,只有当你在那个位置可以做一些现实的事情时才能发现异常 - 即恢复,回滚,计划B等。如果你无能为力,只需让它通过上链。如果该位置有可用的特定有用数据可以增加原始异常并因此有助于调试,那么您应该只捕获并抛出一个新异常。

我来自思想学派,应该使用try / catch块,而不是重新抛出异常。如果您执行的代码很可能出错,那么应该处理,记录并返回一些代码。重新抛出异常仅用于稍后在应用程序生命周期中重新记录。

这是一篇关于如何使用HttpModule处理异常的有趣帖子: http://blogs.msdn.com/rahulso/archive/2008/07/13/how-to-use-httpmodules-to -troubleshoot-your-asp-net-application.aspx http://blogs.msdn.com/rahulso/archive/2008/07/18 /asp-net-how-to-write-error-messages-into-a-text-file-using-a-simple-httpmodule.aspx

查看 ELMAH 。它做你正在谈论的事情。很好。

当我创建库时,我尝试始终为调用者提供减少的异常数量来处理。例如,考虑一个连接到sql数据库的Repository组件。从理论上可以抛出从sql客户端异常到无效的强制转换异常的异常。其中许多都是清楚记录的,可以在编译时考虑。所以,我尽可能多地捕获它们,将它们放在一个异常类型中,例如RepositoryException,并让该异常汇总调用堆栈。

保留原始异常,因此可以诊断原始异常。但是我的调用者只需要担心处理一个异常类型而不是用大量不同的catch块来丢弃它们的代码。

当然,这有一些问题。最值得注意的是,如果调用者可以处理其中一些异常,他们必须在RepositoryException中查找,然后打开内部异常的类型来处理它。它比单个异常类型的单个catch块更不干净。但是,我不认为这是一个很大的问题。

听起来抛出的异常不应该作为异常实现。

无论如何,我会说,因为这个BaseApplicationException是一个通用的通用异常,所以抛出更具特定于上下文的异常会更好。因此,当您尝试从数据库中检索实体时,您可能需要EntityNotFoundException。这样,在进行调试时,您不必搜索内部异常和堆栈跟踪来查找真正的问题。如果此BAseApplicationException正在收集有关异常的信息(如跟踪内部异常),那么这应该不是问题。

只有当我无法接近代码中实际发生异常的地方时,我才会使用HttpModule。根据BaseApplicationexception的错误信息,你真的不希望HttModule OnError事件是一个巨大的switch语句。

总而言之,当您可以提供更具体的例外情况时,抛出不同的例外是值得的,这些例外可以立即告诉您问题的根源。

根据我的经验,捕获异常,将错误添加到Server(?)对象。这将允许.NET执行它需要做的事情,然后显示您的异常。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top