c# - 我不应该捕获哪些异常?

标签 c# .net exception-handling

我有一个运行长批处理的应用程序,其中可能会抛出许多异常。如果在批处理中的一个项目期间抛出非关键异常,我想简单地记录它并继续,这样我们可以稍后解决问题,同时让其他批处理项目继续。

一些异常,例如 OutOfMemoryException,对整个应用程序来说是毁灭性的,我想重新抛出这些异常,以便它们冒泡到全局异常处理程序,该处理程序将记录错误并停止应用程序。

所以我的问题是,是否有一个相当短的关键异常列表,我可以在我的下层异常处理程序中重新抛出这些异常,同时抑制(在记录之后)其他所有内容?

谢谢!

编辑:详细说明一下,这是我的程序的基本结构

foreach(var item in longItemList)
{
   try
   {
      bigDynamicDispatchMethod(item);
   }
   catch(Exception ex)
   {
      logException(ex);
   }
}

可能会抛出大量异常,因为此循环几乎位于我的应用程序的顶层。我项目中 99% 的代码都在 dispatch 方法后面。我在较低级别进行了合理的异常处理,但错误仍然存​​在,我不想在抛出异常后停止批处理中其他不相关的进程。

试图找出哪些异常可以在我的应用程序的其他任何地方抛出似乎是一项艰巨的任务,而且似乎获得关键异常的黑名单会更简单。

有没有更好的方法来构建我的应用来处理这个问题?我乐于接受建议。

最佳答案

您不需要“坏”异常列表,默认情况下您应该将所有异常都视为坏异常。只捕获您可以处理并从中恢复的内容。 CLR can notify 处理未处理的异常,以便您可以适本地记录它们。吞下除了黑名单之外的所有异常都不是修复错误的正确方法。那只会掩盖他们。阅读 thisthis

Do not exclude any special exceptions when catching for the purpose of transferring exceptions.

Instead of creating lists of special exceptions in your catch clauses, you should catch only those exceptions that you can legitimately handle. Exceptions that you cannot handle should not be treated as special cases in non-specific exception handlers. The following code example demonstrates incorrectly testing for special exceptions for the purposes of re-throwing them.

public class BadExceptionHandlingExample2 {
    public void DoWork() {
        // Do some work that might throw exceptions.
    }
    public void MethodWithBadHandler() {
        try {
            DoWork();
        } catch (Exception e) {
            if (e is StackOverflowException ||
                e is OutOfMemoryException)
                throw;
            // Handle the exception and
            // continue executing.
        }
    }
}

一些其他规则:

Avoid handling errors by catching non-specific exceptions, such as System.Exception, System.SystemException, and so on, in application code. There are cases when handling errors in applications is acceptable, but such cases are rare.

An application should not handle exceptions that can result in an unexpected or exploitable state. If you cannot predict all possible causes of an exception and ensure that malicious code cannot exploit the resulting application state, you should allow the application to terminate instead of handling the exception.

Consider catching specific exceptions when you understand why it will be thrown in a given context.

You should catch only those exceptions that you can recover from. For example, a FileNotFoundException that results from an attempt to open a non-existent file can be handled by an application because it can communicate the problem to the user and allow the user to specify a different file name or create the file. A request to open a file that generates an ExecutionEngineException should not be handled because the underlying cause of the exception cannot be known with any degree of certainty, and the application cannot ensure that it is safe to continue executing.

Eric Lippert 将所有异常分为 4 组:Fatal、'Boneheaded'、Vexing、Exogenous。以下是我对 Eric 的建议的解读:

  Exc. type | What to do                          | Example
------------|-------------------------------------|-------------------
Fatal       | nothing, let CLR handle it          | OutOfMemoryException
------------|-------------------------------------|-------------------
Boneheaded  | fix the bug that caused exception   | ArgumentNullException
------------|-------------------------------------|-------------------
Vexing      | fix the bug that caused exception   | FormatException from 
            | (by catching exception  because     | Guid constructor
            | the framework provides no other way | (fixed in .NET 4.0 
            | way of handling). Open MS Connect   | by Guid.TryParse)
            | issue.                              | 
------------|-------------------------------------|-------------------
Exogenous   | handle exception programmatically   | FileNotFoundException 

这大致相当于Microsoft's 的分类:Usage、Program error和System failure。 您还可以使用 FxCop 等静态分析工具来执行这些规则的 some

关于c# - 我不应该捕获哪些异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7152354/

相关文章:

c# - 使用接口(interface)时实现类的特定类型

c# - 重复命名空间名称的问题

C# 创建一个比较两个成员属性的 LambdaExpression(对于 EF Core HasQueryFilter)

javascript - 页面刷新 (F5) 后丢失 Ajax-SliderExtender

c# - 圆上的点按角度分布不均匀

c# - 向 C# 公开 ISO C++ 类

c# - 根级别的数据无效。第 1 行,位置 1 MonoTouch

python-3.x - 在Python中处理COMError?

.net - .NET 中的错误代码/消息管理方法

.net - 如何捕获特定的 OleDbException?