捕获System.Exception总是一个坏习惯吗?

Use*_*ser 11 c# exception-handling

请考虑以下代码,它会抛出三个不同的异常(即System.Configuration.ConfigurationErrorsException,System.FormatExceptionSystem.OverflowException):

int SomeInt = Convert.ToInt32(ConfigurationManager.AppSettings["SomeIntValue"]);
Run Code Online (Sandbox Code Playgroud)

异常是不同的,因此在实践中我应该有三个不同的catch块来处理每个特定的异常.但是,在这种特殊情况下,所有异常都以相同的方式处理:将日志写入,例如,EventViewer,并显示一条消息,通知配置错误......在这个特定的原因中,使用它太糟糕了

try
{
    int SomeInt = ConfigurationManager.AppSettings["SomeIntValue"];
}
catch (Exception ThisException)
{
    /* Log and display error message. */
}
Run Code Online (Sandbox Code Playgroud)

或者我应该使用这三个catch块并在每个块中重复代码?

Mik*_*son 8

有关此问题的讨论,请参阅C#异常处理漏洞.

简而言之,如果你捕获一般的异常,你应该检查它是否是预期的类型之一,如果没有重新抛出它.

更新(并且有点超出范围)

还有几次我认为做一个全部捕获是有效的.这是非常罕见的,但有时在web服务中,或者如果你在asp.net中的后台线程上执行某些操作,并且异常会重新启动整个应用程序,如果你依赖于它,人们可能会丢失会话.


Joh*_*soe 2

我不认为这是不好的做法。如果您想要的功能是“每当此代码引发异常时,就采取这些操作”,那么我认为捕获 System.Exception 是非常合适的。

在我看来,您正在包装一个非常具体的框架函数而不是一大块自定义代码这一事实也有所帮助。

  • 我不同意。这不应该是您想要的功能。如果发生恶意行为,那么您的代码将幸福地忽略它,因为它捕获所有异常,而不是仅捕获它期望并知道如何处理的异常。为自己节省一分钟的打字时间会导致代码中出现安全问题,并可能掩盖您自己引入的错误。 (6认同)
  • @iheanyi:不要在最高级别使用 catch-all,而是使用 System.AppDomain.UncatchedExceptionHandler。 (4认同)
  • 我同意@iheanyi。这是一个不好的做法。异常处理是关于“处理”异常。你应该只抓住那些你知道如何处理的人。让其他人冒泡。但请记住,拥有一个全局异常处理程序来捕获所有未捕获的异常总是一个好主意。这个机制至少应该记录错误,但也有一些智能来确定如何响应更严重的异常。例如,如果由于磁盘空间不足而收到 IOException,该怎么办?如果你只是接受更高层的异常怎么办? (2认同)
  • 我同意@mikesigs 的观点。在应用程序的顶层,有一个全局的包罗万象的异常处理程序是合适的。此时,您仍然无法处理异常,适当的响应是记录然后“重新启动”您的应用程序或记录然后“终止”您的应用程序。 (2认同)