我不应该赶上哪些异常? [英] Which exceptions shouldn't I catch?

查看:195
本文介绍了我不应该赶上哪些异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个运行长的批处理过程,其中许多例外可能抛出一个应用程序。如果一个非关键异常期间在批一个项目抛出,我想只需登录并继续,所以我们可以在以后解决问题,同时让另一批项目继续进行。

有些例外,如 OutOfMemoryException异常,是毁灭性的应用程序作为一个整体,而这些我想再次抛出,使他们冒泡到全局异常处理这将记录错误并停止该应用程序。

所以我的问题是,有没有我可以在我的下异常处理程序而重新抛出异常关键的reasonbly短名单燮pressing(登录后)一切?

谢谢!

编辑:要详细一点,这里是我的程序的基本结构

 的foreach(在longItemList VAR项)
{
   尝试
   {
      bigD​​ynamicDispatchMethod(项目);
   }
   赶上(例外前)
   {
      logException(前);
   }
}  

有一个潜在的巨大可能被抛出,因为这个环是pretty的多在我的应用程序的顶部级别的异常的数目。 99%的code在我的项目是分派方法落后。我做合理的异常处理在较低的水平,但仍然漏洞的工作方式,我不希望有一个异常被抛出后,停止其他不相关的进程中的批次。

试图找出哪些异常可能会被抛出其他地方在我的应用程序似乎是一个艰巨的任务,它似乎是,它会更简单,以获取重要的例外的黑名单。

有没有更好的方式来构建我的应用程序来处理呢?我愿意接受建议。

解决方案

您不需要的坏的例外列表中,你应该把一切都那么糟糕默认。唯一的缺点是什么,你可以处理,并从中恢复。 CLR 可以 <一href="http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx">notify你未处理的异常,这样就可以适当地记录它们。吞咽一切,但一个列入黑名单的例外是不是一个正确的方式来解决您的错误。这将只是掩盖他们。阅读和的这个

  

捕为目的时,不要排除任何特别的例外   的转移例外。

     

而不是在你的catch子句创建特殊的例外列表中,   你应该只捕获这些异常,你可以合法   处理。例外,你不能处理不应该被视为   特殊情况下的非特异性异常处理程序。该   下面code示例演示了不正确的测试专用   例外的重新投掷他们的目的。

 公共类BadExceptionHandlingExample2 {
    公共无效的DoWork(){
        //做可能会抛出异常的一些工作。
    }
    公共无效MethodWithBadHandler(){
        尝试 {
            做工作();
        }赶上(例外五){
            如果(e是StackOverflowException ||
                e是OutOfMemoryException异常)
                扔;
            //处理异常和
            //继续执行。
        }
    }
}
 

很少有其他的规则:

  

避免通过捕获非特异性异常,如处理错误   System.Exception的,System.SystemException,等等,在应用   code。在有些情况下,当应用程序中的错误处理是   可以接受的,但这种情况很少发生。

     

这是应用程序不应该处理异常,可导致   意外或利用的状态。如果你不能predict所有可能的   导致异常,并确保恶意code不能利用   生成的应用程序的状态,你应该允许应用程序   终止,而不是处理异常。

     

考虑捕捉特定异常,当你明白为什么   将被扔在一个给定的范围内。

     

您应该只捕获那些你可以恢复的异常。对于   例如,出现FileNotFoundException起因于试图打开   一个不存在的文件可以由一个应用程序来处理,因为它可以   通信的问题给用户,并允许用户指定一个   不同的文件名或创建文件。打开一个文件请求   生成因为ExecutionEngineException不应被处理   异常的根本原因不能用任何已知的程度   确定性,并且该应用程序不能确保它是安全的   继续执行。

埃里克利珀所有异常分为4组:致命的,愚蠢的,让人头疼的,外生的。以下是埃里克的建议我跨pretation:

  EXC。键入|怎么办|例
------------ | ------------------------------------- | -------------------
致命|什么都没有,让CLR处理它| OutOfMemoryException异常
------------ | ------------------------------------- | -------------------
愚蠢的|解决引起异常错误| ArgumentNullException
------------ | ------------------------------------- | -------------------
令人烦恼|解决引起异常错误|出现FormatException从
            | (通过捕获异常,因为|的Guid构造
            |该框架提供了没有其他方法| (固定在.NET 4.0中
            |的处理方式)。打开MS连接|通过Guid.TryParse)
            |问题。 |
------------ | ------------------------------------- | -------------------
外源性|以编程方式处理异常| FileNotFoundException异常
 

这是大致相当于微软分类:用法,程序出错和系统故障。 您也可以使用静态分析工具,如的FxCop 执行<一个href="http://blogs.msdn.com/b/$c$canalysis/archive/2006/06/14/faq_3a00_-why-does-fxcop-warn-against-catch_2800_exception_29003f00_-_2d00_-part-1-_5b00_nick-guerrera_5d00_.aspx">some这些规则。

I have an app that runs a long batch process where many exceptions could potentially be thrown. If a non-critical exception is thrown during one item in the batch, I want to simply log it and continue, so we can fix the problem later while letting the other batch items continue.

Some exceptions, such as OutOfMemoryException, are devastating to the app as a whole, and these I would like to rethrow so that they bubble up to global exception handler which will log the error and stop the app.

So my question is, is there a reasonbly short list of critical exceptions that I can rethrow in my lower exception handler while suppressing (after logging) everything else?

Thanks!

Edit: To elaborate a little, here is the basic structure of my program

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

There are potentially a huge number of exceptions that could be thrown because this loop is pretty much at the top level of my app. 99% of the code in my project is behind the dispatch method. I do reasonable exception handling at lower levels, but bugs still work their way in and I don't want to stop other unrelated processes in the batch after an exception is thrown.

Trying to find which exceptions could be thrown everywhere else in my app seems like a daunting task, and it seemed to be that it would be simpler to get a blacklist of critical exceptions.

Is there a better way to structure my app to deal with this? I am open to suggestions.

解决方案

You don't need a list of 'bad' exceptions, you should treat everything as bad by default. Only catch what you can handle and recover from. CLR can notify you of unhandled exceptions so that you can log them appropriately. Swallowing everything but a black listed exceptions is not a proper way to fix your bugs. That would just mask them. Read this and this.

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.
        }
    }
}

Few other rules:

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 classifies all exceptions into 4 groups: Fatal, 'Boneheaded', Vexing, Exogenous. Following is my interpretation of Eric's advice:

  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 

This is roughly equivalent to Microsoft's categorization: Usage, Program error and System failure. You can also use static analysis tools like FxCop to enforce some of these rules.

这篇关于我不应该赶上哪些异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆