Exception 捕捉到一般性异常真的那么糟糕吗?

Exception 捕捉到一般性异常真的那么糟糕吗?,exception,Exception,在使用FXCop分析一些遗留代码时,我突然想到,在try块中捕获一般异常错误是否真的那么糟糕,或者您是否应该查找特定的异常。请看一张明信片。好吧,我看不出捕获一般异常与捕获特定异常之间有什么区别,只是当有多个捕获块时,您可以根据异常情况做出不同的反应 总之,您将使用泛型的异常捕获IOException和NullPointerException,但您的程序的反应方式可能不同。我认为一个好的指导原则是只捕获框架内的特定异常(以便主机应用程序可以处理磁盘填充等边缘情况),但我不明白为什么我们不能捕获应

在使用FXCop分析一些遗留代码时,我突然想到,在try块中捕获一般异常错误是否真的那么糟糕,或者您是否应该查找特定的异常。请看一张明信片。

好吧,我看不出捕获一般异常与捕获特定异常之间有什么区别,只是当有多个捕获块时,您可以根据异常情况做出不同的反应


总之,您将使用泛型的
异常捕获
IOException
NullPointerException
,但您的程序的反应方式可能不同。

我认为一个好的指导原则是只捕获框架内的特定异常(以便主机应用程序可以处理磁盘填充等边缘情况),但我不明白为什么我们不能捕获应用程序代码中的所有异常。很简单,有时候你不希望应用程序崩溃,不管发生什么错误。

大多数情况下,捕获一般异常是不必要的。当然,有些情况下你没有选择,但在这种情况下,我认为是这样的最好检查您为什么需要捕获它。也许您的设计中有错误。

除非您在应用程序前端执行一些日志记录和清理代码,否则我认为捕获所有异常是不好的

我的基本经验是捕获所有您期望的异常,其他任何异常都是bug


如果你抓住了一切并继续前进,这有点像在汽车仪表板上的警示灯上贴上一块膏药。你再也看不见了,但这并不意味着一切都好。

我认为这有两个要点

首先,如果您不知道发生了什么异常,您希望如何从中恢复。如果您预期用户可能键入错误的文件名,那么您可以预期FileNotFoundException并告诉用户重试。如果相同的代码生成了NullReferenceException,而您只是告诉用户重试,那么他们将不知道发生了什么发生了什么


其次,FxCop指南确实关注库/框架代码-并非所有规则都设计为适用于EXE或ASP.Net网站。因此,拥有一个全局异常处理程序来记录所有异常并很好地退出应用程序是一件好事。

显然,这是唯一真正答案的问题之一是“视情况而定”

它取决于捕获异常的位置。在一般情况下,库在捕获异常时应该更加保守,而在程序的顶层(例如,在主方法或控制器中的操作方法的顶部等),您可以更自由地捕获


原因是,例如,您不想捕获库中的所有异常,因为您可能会掩盖与库无关的问题,如“OutOfMemoryException”另一方面,如果你说的是在main()方法中捕获异常,该方法捕获异常,显示异常,然后退出……那么,在这里捕获任何异常都可能是安全的

捕获所有异常的最重要规则是,您永远不应该只是默默地吞下所有异常……例如,Java中的类似内容:

try { 
    something(); 
} catch (Exception ex) {}
或者在Python中:

try:
    something()
except:
    pass
因为这些可能是最难追踪的问题

一个很好的经验法则是,你应该只捕获你自己能够正确处理的异常。如果你不能完全处理异常,那么你应该让能够处理异常的人来处理它。

是的!(应用程序的“顶部”除外)

通过捕获异常并允许代码继续执行,表示您知道如何处理、规避或修复特定问题。表示这是一种可恢复的情况。。捕获异常或系统异常意味着您将捕获诸如IO错误、网络错误、m以外的问题emory错误、缺少代码错误、空指针解引用等等。说你能处理这些是谎言

在一个组织良好的应用程序中,这些不可恢复的问题应该在高层处理


此外,随着代码的发展,您不希望您的函数捕获将来添加到被调用方法的新异常。

在我看来,您应该捕获您期望的所有异常,但此规则适用于除接口逻辑之外的任何事物。在调用堆栈中,您可能应该创建一种捕获异常的方法所有例外情况,进行一些日志记录/给用户反馈,如果需要和可能,优雅地关闭


没有什么比应用程序崩溃更糟糕的了,一些用户不友好的stacktrace被转储到屏幕上。它不仅会给出(可能是不需要的)深入了解您的代码,但这也会混淆您的最终用户,有时甚至会将他们吓跑到竞争对手的应用程序中。

捕获所有异常的问题是,您可能正在捕获您不希望捕获的异常,或者确实是您不应该捕获的异常。事实上,任何类型的异常都表明有些地方出了问题,您必须在继续之前进行整理,否则最终可能会出现数据完整性问题和其他不易追踪的bug

举一个例子,在一个项目中,我实现了一种称为CriticalException的异常类型。这表示一种错误情况,需要开发人员和/或管理人员进行干预,否则客户会收到错误的账单,或者可能会导致其他数据完整性问题。它也可以用于其他类似情况,只要记录异常是不够的,需要发送电子邮件警报
    catch (final RemoteException exc)
    {
        exc.printStackTrace();
    }
    catch (final IntentSender.SendIntentException exc)
    {
        exc.printStackTrace();
    }
    catch (final IabHelper.IabAsyncInProgressException exc)
    {
        exc.printStackTrace();
    }
    catch (final NullPointerException exc)
    {
        exc.printStackTrace();
    }
    catch (final IllegalStateException exc)
    {
        exc.printStackTrace();
    }
    catch (final Exception exc)
    {
        exc.printStackTrace();
    }