C#中的常规异常处理

时间:2009-10-27 10:07:13

标签: c# exception-handling

我正在通过FxCop运行一些代码,目前正在考虑清除所有非破坏性违规。

代码本身有一些try / catch块实例,它们只捕获一般异常;

try
{
    // Some code in here that could throw an exception
}
catch(Exception ex)
{
    // Exception Thrown ... sort it out!
}

现在我们都知道这是不好的做法,但我认为我知道如何正确地做到这一点 - 但是FxCop有其他想法!

假设try块中的代码可能抛出IO异常 - 并且只有IO异常。这样做应该没有错:

try
{
    // Code in here that can only throw an IOException
}
catch (System.IO.IOException ioExp)
{
    // Handle the IO exception or throw it
}
catch (System.Exception ex)
{
    // Catch otherwise unhandled exception
}

但是FxCop不同意我的观点......它仍然将此标记为违规行为,因为我抓住了System.Exception

这是非常糟糕的做法,还是应该/我能否安全地忽略这种违规行为?

8 个答案:

答案 0 :(得分:6)

我同意FxCop和其他大多数答案:不要抓住System.Exception 永远,除非它在您的应用程序中处于最高级别以记录意外(因此致命) )异常,然后轰炸应用程序。 Also check out this question that's basically about the same thing.

其他一些有效的例外可能是:

  • 为了重新抛出更具描述性的一个原因而捕获异常。
  • 在需要比ExpectedExceptionAttribute更复杂的单元测试代码中。
  • 在外观库代码中,仅存在以保护调用者免于复杂地调用某些外部(Web)服务,而不会实际上自身失败,无论外部系统可能出现多么糟糕。

答案 1 :(得分:5)

我同意其他答案catch (Exception ex)如果你是

就没问题
  1. 只需记录并重新抛出异常或
  2. 在应用程序的最高级别(UI)执行此操作。
  3. 还有一种情况可以理解:在编写无人值守代码(例如某些系统服务)时,保持程序运行(如果有的话)是完全合理的(定义明确的子任务因任何原因失败。当然,必须注意确保记录问题的原因,并且(可能)在一段时间后再次尝试该任务。

答案 2 :(得分:4)

如果您编写库(框架),那么FxCop是100%正确的。

你捕获异常 - 它是什么意思?你知道他们为什么扔了。你确定你知道所有可能的原因吗?

如果您只编写应用程序,那么可能会有变化。例如,如果您捕获所有未处理的日志记录异常。

答案 3 :(得分:4)

灰色区域......

在一个理想的世界中,你总是会抓住一个明确的异常,因为从理论上讲,这是唯一可以合理处理的东西 - 其他任何东西都应该渗透到某个顶级处理程序。

问题是我们不一定生活在一个理想的世界中,并且可能希望使用通用处理程序将有关通用异常(参数等)的其他信息累积到异常中和/或在传递之前执行其他日志记录异常备份树,并且在任何情况下 - 在适当的级别 - 以安排我们的最终用户在UI中看不到原始异常的事情。对此的反击是建议当新错误发生在较低级别(而不是到达您的应用程序级别处理程序)时,然后添加可以为您捕获的异常特定处理 - 但是可能存在部署问题一种解决方案,其中包含一些代码的通用案例,无论出于何种原因,这些代码更容易出现人们可能喜欢的未处理异常。

如果是我,我可能会按照装配基础考虑装配旗帜......

P.S。我假设你没有一个处理程序可以吞下异常并允许应用程序继续运行。

答案 4 :(得分:3)

你应该吞下你知道如何处理的异常。捕获异常而不抛出异常(直接或包装在特定异常中)意味着您在应用程序的上下文中知道异常的细节。由于Exception可以是任何东西,因此您不太可能知道如何处理它。

如果您只是记录异常,那就没什么大不了的,只需将其记录下来并将其扔到外层来处理或捕获。

答案 5 :(得分:2)

FxCopy说具体违规是什么?如果您只想记录有关异常的信息然后重新抛出它,那么这是完全有效的,尽管还有其他方法可以完成。如果你正在重新提升它,请确保你只使用:

 throw;

而不是

 throw ex;

也许这就是问题?

答案 6 :(得分:2)

如果块中的代码只抛出IOException,那么为什么还要捕获System.Exception呢?

然后,您希望实现的FxCop指南的符合程度是您的选择。例如,我会发现在最高级别捕获每个异常并记录所有可用信息没什么不好。

答案 7 :(得分:2)

您应该只捕获可以执行某些操作的异常。否则,让异常传播到调用者,或者,例如,在Gui应用程序中,异常应由通用catch all处理程序处理,然后记录。请参阅:UnhandledException 所以不要抓住,除非你打算用它做点什么......不可否认,这可能只是记录错误。

修改 另请查看Application.ThreadException