在使用FXCop分析一些旧代码时,我想到的是,在try块中捕获一般的异常错误确实很不好,或者您是否正在寻找特定的异常。 请在明信片上提出想法。

===============>>#1 票数:90 已采纳

显然,这是唯一的答案是“取决于”的问题之一。

它主要取决于您在哪里捕获异常。 通常,库应该在捕获异常时更加保守,而在程序的顶层(例如,在主方法中或在控制器的action方法的顶部等)中,捕获的内容可以更加自由。

这样做的原因是,例如,您不想捕获库中的所有异常,因为您可能掩盖了与库无关的问题,例如“ OutOfMemoryException”,您实际上更喜欢冒泡,以便用户可以另一方面,如果您正在谈论的是在main()方法中捕获异常的方法,该方法捕获异常,先显示该异常,然后退出...好吧,在这里捕获几乎所有异常都是安全的。

捕获所有异常的最重要规则是,您绝不应该默默地吞下所有异常……例如,Java中这样的代码:

try { 
    something(); 
} catch (Exception ex) {}

或在Python中:

try:
    something()
except:
    pass

因为这些可能是一些最难追踪的问题。

一个好的经验法则是,您应该只捕获可以正确处理的异常。 如果您不能完全处理异常,则应让它冒犯给可以处理的人。

===============>>#2 票数:25

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

我的基本经验法则是捕获您期望的所有异常,而其他任何东西都是错误。

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

===============>>#3 票数:15

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

通过捕获异常并允许代码执行继续,您表示您知道如何处理和规避或解决特定问题。 您是在说这是可恢复的情况 捕获Exception或SystemException意味着您将捕获诸如IO错误,网络错误,内存不足错误,代码丢失错误,空指针取消引用之类的问题。 说您可以处理这些是一个谎言。

在一个组织良好的应用程序中,这些不可恢复的问题应在堆栈中较高的位置处理。

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

===============>>#4 票数:11

我认为您应该捕获所有您期望的异常,但是该规则适用于除接口逻辑以外的任何内容。 在调用堆栈的整个过程中,您可能应该创建一种捕获所有异常的方法,进行一些日志记录/提供用户反馈,并在需要和可能的情况下正常关闭。

没有比将用户不友好的堆栈跟踪转储到屏幕而崩溃的应用程序更糟糕的了。 它不仅使(也许是不需要的)洞察您的代码,而且还使最终用户感到困惑,有时甚至将它们吓到竞争的应用程序。

===============>>#5 票数:8

关于这个问题,已经有很多哲学讨论(更像是论据)。 我个人认为,最糟糕的事情是吞下异常。 下一个最糟糕的情况是,允许异常气泡冒泡到表面,使用户在屏幕上看到充满技术性庞然大物的讨厌屏幕。

===============>>#6 票数:4

好吧,我看不到捕获一般异常或特定异常之间的任何区别,除了拥有多个catch块时,您可以根据异常是什么做出不同的反应。

总之,您将使用通用Exception捕获IOExceptionNullPointerException ,但是程序的响应方式可能有所不同。

===============>>#7 票数:3

我认为这是双重的。

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

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

===============>>#8 票数:3

与捕获所有异常的问题是,你可能会赶上的,你不要指望,或确实的,你应该追赶。 事实是,任何类型的异常都表明出了点问题,您必须先对其进行分类,然后再继续进行,否则可能会遇到数据完整性问题和其他不易查找的错误。

举一个例子,在一个项目中,我实现了一个称为CriticalException的异常类型。 这表示错误状态,需要开发人员和/或管理人员进行干预,否则客户将被错误地记帐,否则可能会导致其他数据完整性问题。 当仅记录异常是不够的,并且需要发送电子邮件警报时,也可以在其他类似情况下使用它。

另一位没有正确理解异常概念的开发人员然后包装了一些代码,这些代码可能会在通用的try ... catch块中抛出此异常,该块会丢弃所有异常。 幸运的是,我发现了它,但是它可能会导致严重的问题,尤其是因为本来应该抓住的“非常罕见”的极端情况比我预期的要普遍得多。

因此,通常来说,捕获通用异常是不好的,除非您100%确信您确切知道将在何种情况下抛出哪种异常。 如有疑问,请让它们冒泡到顶级异常处理程序。

这里类似的规则是永远不会抛出System.Exception类型的异常。 您(或其他开发人员)可能希望在调用堆栈中更高的位置捕获特定异常,同时让其他人通过。

(但是要注意一点。在.NET 2.0中,如果线程遇到任何未捕获的异常,它将卸载整个应用程序域。因此,应将线程的主体包装在通用try ... catch块中并传递全局异常处理代码中捕获的所有异常。)

===============>>#9 票数:2

我想扮演魔鬼的拥护者,以捕获Exception并将其记录并重新抛出。 例如,如果您在代码中的某个地方并且发生​​了意外的异常,可以捕获它,记录在简单的堆栈跟踪中无法获得的有意义的状态信息,然后将其重新扔到上层,则可能是必要的处理。

===============>>#10 票数:1

有两种完全不同的用例。 第一个是大多数人正在考虑的问题,对需要检查异常的某些操作进行尝试/捕获。 无论如何,这都不是万能的。

但是,第二个方法是在程序可以继续执行时阻止程序中断。 这些情况是:

  • 所有线程的顶部(默认情况下,异常将消失,没有任何痕迹!)
  • 在您希望永不退出的主处理循环中
  • 在循环内部处理一系列对象,其中一个故障不应阻止其他故障
  • “主”线程的顶部-您可以在此处控制崩溃,例如在内存不足时将少量数据转储到stdout。
  • 如果您有一个运行代码的“运行程序”(例如,如果有人向您添加了一个侦听器,然后您调用了该侦听器),那么在运行代码时,您应该捕获Exception来记录问题并让您继续通知其他侦听器。

这些情况下,您总是希望捕获异常(有时甚至是Throwable)以捕获编程/意外错误,将其记录下来并继续。

===============>>#11 票数:0

我认为一个好的指导方针是仅捕获框架内的特定异常(以便主机应用程序可以处理磁盘填充等边缘情况),但我不明白为什么我们不应该捕获所有异常应用程序代码中的异常。 有时候,无论发生什么问题,您都不希望应用程序崩溃。

===============>>#12 票数:0

大多数时候不需要捕获一般异常。 当然,有些情况下您别无选择,但是在这种情况下,我认为最好检查一下为什么需要抓住它。 也许您的设计有问题。

===============>>#13 票数:0

抓住一般的例外情况,我感觉就像是在燃烧的建筑物内拿着炸药,然后放出引信。 它可以帮助一小会儿,但是炸药会在一段时间后反吹。

当然,在某些情况下,有必要捕获一般的Exception,但仅用于调试目的。 错误和错误应该固定,而不是隐藏。

===============>>#14 票数:0

对于我的IabManager类(用于在线应用内结算)(来​​自TrivialDrive示例在线版),我注意到有时我会处理很多异常情况。 到了不可预测的地步。

我意识到,只要我停止尝试在一个异常发生后消费应用内产品的尝试(这是大多数异常发生(消费而非购买)的地方),我就会很安全。

我只是将所有异常更改为一般异常,现在不必担心会引发任何其他随机的,不可预测的异常。

之前:

    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();
    }

===============>>#15 票数:0

不受欢迎的意见:并非如此。

捕获所有可以有意义地恢复的错误。 有时,仅此而已。

在我的经验,更重要的地方除了来自比异常抛出实际。 如果您将例外情况留在狭窄的地方,那么通常不会吞下任何本来有用的东西。 错误类型中编码的大多数信息都是辅助信息,因此通常无论如何您最终都会有效地捕获所有这些信息(但是现在您必须查找API文档以获取可能的异常的总集合)。

请记住,几乎在每种情况下,某些异常都应该冒出来,例如Python的KeyboardInterruptSystemExit 幸运的是,对于Python而言,它们被保存在异常层次结构的单独分支中,因此您可以通过捕获Exception来使其冒泡。 精心设计的异常层次结构使这种事情真的很简单。

捕获一般异常的主要时间是在处理需要清理的资源时(可能在finally子句中),这会导致严重的问题,因为捕获所有的处理程序很容易错过这类事情。 幸运的是,对于使用defer ,C ++和Rust中的Python的with或RAII这样的语言,这实际上不是问题。

  ask by Triss translate from so

未解决问题?本站智能推荐:

3回复

抓住甚至价值的例外是真的吗?

我目前正在尝试编写一个迭代序列(x)的代码,搜索用户输入的单词。 下面是代码。 上面的代码在迭代过程中工作正常,但是在迭代序列之后总会返回ValueError。 我试图通过添加以下内容来纠正这个问题 认为一旦迭代到达序列的末尾就会停止,但是在从序列返回找到的值之后它继续抛
2回复

抓住两个例外,一个是另一个的超类

我有一个解析文本和创建对象的工厂方法。 在此工厂方法中,有一个部分可以读取直到流的末尾。 我编写的另一种方法实现了解析器的这一部分。 这是我正在使用的代码: 我想以不同于IOException的方式处理EOFException,因此我在不同的catch()块中捕获它们。 我的问题
1回复

什么时候抓住了一个例外?

即使我认为我已经捕获了异常,但我还是以未捕获的异常终止了这个。 这是一些示例代码 它产生(在报告错误:“x non-null”之后 )所述消息(使用clang ++和std=c++11 )。 那么, 到底有时除了被抓,因此认为在未捕获的意义上terminate()不(再)报告呢?
6回复

为什么抛出一个非例外被认为是糟糕的设计?

我有一些代码来对对象的矢量进行排序。 如果任何对象无效,我想立即停止排序并报告错误。 在错误中,我想要包含无效对象的描述(无论哪一个有多少)。 这是我的代码(不完整,但我希望你能跟着我): 现在,我对我的代码有点不确定,因为我听说所有异常都应该是异类的子类,并且抛出不是异常实例
10回复

为什么不抓住一般例外

我的VS刚刚告诉我; 警告2 CA1031:Microsoft.Design:修改'Program.Main(string [])'以捕获比“Exception”更具体的异常或重新抛出异常。 我为什么要那么做? 如果我这样做,并没有捕获所有异常来处理它们,我的程序崩溃与所有流
3回复

为什么没有抓住这个例外

我有以下代码 我忘了包含一个jdom.jar库的依赖库。 当我运行应用程序时,我看到了这个错误。 根据JDOM文档,newInsance()方法抛出一个JDOMEXCeption,所以它不应该捕获错误? 另外,我如何避免添加catch(Exception e)子句以避免未
1回复

抓住Angular 2例外

如果Angular 2遇到内部异常,则不会将其记录到控制台。 如何检测以下异常? 有没有可用的订阅? 这样的文件在哪里?
4回复

抓住致命的例外并继续

我知道,根据它的定义,一个致命的异常应该杀死执行,不应该被压制,但这是问题所在。 我正在运行一个脚本,在数据库中擦除,解析和存储大约10,000页。 这需要几个小时,在极少数情况下(1000个中有1个)页面无法解析并抛出致命异常。 目前,我这样做: 我能做点什么吗
1回复

“尝试”没有抓住例外情况

我正在使用hedis并试图处理服务器死机的情况。 根据文件: 与服务器的连接丢失:如果连接丢失,命令函数将抛出ConnectionLostException。 它只能在runRedis之外捕获。 所以我假设我想捕获ConnectionLostException。 然而,虽
2回复

泽西岛无法抓住任何杰克逊的例外

对于我的REST api,我使用jersey和ExceptionMapper来捕获全局异常。 它适用于我的应用程序抛出的所有异常,但我无法捕获杰克逊抛出的异常。 例如,我的一个端点接受包含枚举的对象。 如果请求中的Json有一个不在enum jersey中的值,则返回此异常 即