Is it always a bad practice to catch System.Exception?
请考虑以下代码,它抛出了三个不同的异常(即
1 | int SomeInt = Convert.ToInt32(ConfigurationManager.AppSettings["SomeIntValue"]); |
异常是不同的,因此在实践中,我应该有三个不同的
1 2 3 4 5 6 7 8 | try { int SomeInt = ConfigurationManager.AppSettings["SomeIntValue"]; } catch (Exception ThisException) { /* Log and display error message. */ } |
还是应该使用三个
有关此问题的讨论,请参阅C异常处理失败。
简而言之,如果捕获了一般异常,那么应该检查它是否是预期的类型之一,如果不重新引发它。
更新(有点超出范围)
还有几次,我认为做一次全力以赴是有效的。这是非常罕见的,但有时在WebServices中,或者在ASP.NET中的后台线程上执行某些操作时,作为异常情况,会重新启动整个应用程序,如果您依赖它,人们可能会丢失会话。
捕获System.Exception是不好的做法。…或者更好的是,除了应用程序的顶级之外,在任何地方处理System.Exception都是不好的做法。你应该做的是:
示例代码:
1 2 3 4 5 6 7 8 9 |
我不认为这是坏做法。如果您想要的功能是"每当这段代码抛出异常时,就执行这些操作",那么我认为捕获System.Exception是完全合适的。
事实上,您包装的是一个非常具体的框架函数,而不是一大块自定义代码,这在我看来也有帮助。
真正需要的是,但是.NET异常层次结构没有提供一种清晰的方法来区分异常,这意味着"请求的操作没有发生,但是系统状态基本上是良好的,除非操作没有发生"所暗示的程度与"CPU着火,甚至试图保存CU"的程度不同。当前用户的工作可能不会使事情变得更糟。"在很多情况下,人们确实应该努力捕获第一种类型的所有异常,而理想情况下不捕获第二种类型的异常。虽然在上述两个级别之外有一些级别,但通常在捕获异常时,人们并不真正关心InvalidArgumentException或InvalidOperationException之间的区别;我们关心的是整个系统状态是有效的还是损坏的。
事实上,如果一个人正在调用文件导入插件,并抛出一个异常,我不确定他是否可以这样做,除非尝试捕获并重新引发真正糟糕的异常,同时让所有其他异常显示一个"无法打开此文件"对话框。希望系统在那一点上的状态本质上就像用户没有试图打开文件一样,但是没有某种标准化的方式来表示异常的严重性,我认为没有任何方法可以确定。
顺便说一下,如果我有自己的druchers,会有一个类exceptionbase,所有的异常都会从中派生;大多数异常都会从异常派生(反过来又从exceptionbase派生),但是像threadabortexception、stackoverflowexception、outofmemoryexception等东西都会从criticalexception派生。这样就可以捕捉到大多数"意外"的异常,而不会意外地扼杀真正糟糕的异常。
在这种特定的情况下,完全可以使用不同的catch块,因为您可以根据获得的异常情况采取不同的操作。
对于前两个,您可以静默地设置一个合理的默认值,以避免不必要地干扰用户,然后希望在保存文件时问题自行解决,对于后一个异常,您可以询问用户是否希望继续加载过程(在这种情况下,您设置了一个合理的默认值),因为配置文件显然已损坏。PTD。
一般来说,我的想法是:对于被抛出的不同类型的异常,我需要采取不同的行动吗?通常情况下,答案是否定的,所以一个空白的
编辑:空白与空白检查一样,不是空块:)
这不一定是坏的做法,坏的做法通常发生在你做愚蠢的事情,在捕捉块。捕获基本异常类是一种很好的安全措施,假定在发生错误时需要做一些事情。捕获特定异常类的情况是最好的清单,当该特定类向您提供可以执行操作的信息时,例如,捕获sqlException可以帮助您查看特定于该类的某些属性,并让您处理该问题。
通常情况下,人们会捕捉到一个异常并做一些愚蠢的事情,比如创建一个新的异常,或者更糟的是,吞下异常的细节。
一个经常被忽略的模式是你可以捕捉,重新表演。
1 2 3 4 5 | catch(Exception ex) { //do something throw; } |
从而保留异常细节。