在使用 FXCop 分析一些遗留代码时,我发现在 try 块中捕获一般异常错误真的很糟糕,或者您应该寻找特定的异常。 请对明信片的想法。

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

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

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

这样做的原因是,例如,您不想捕获库中的所有异常,因为您可能会掩盖与您的库无关的问题,例如“OutOfMemoryException”,您确实希望冒泡,以便用户可以通知等。另一方面,如果您正在谈论在您的 main() 方法中捕获异常,该方法捕获异常,显示它然后退出......好吧,在这里捕获几乎任何异常可能是安全的。

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

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

或者在 Python 中:

try:
    something()
except:
    pass

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

一个好的经验法则是,您应该只捕获可以妥善处理的异常。 如果您无法完全处理异常,那么您应该让它冒泡给可以处理的人。

===============>>#2 票数:29

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

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

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

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

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

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

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

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

===============>>#4 票数:12

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

没有什么比应用程序因某些用户不友好的堆栈跟踪转储到屏幕而崩溃更糟糕的了。 它不仅让(可能是不需要的)深入了解您的代码,而且让您的最终用户感到困惑,有时甚至将他们吓跑到竞争应用程序中。

===============>>#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

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

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

有两种完全不同的用例。 第一个是大多数人正在考虑的一个,在一些需要检查异常的操作周围放置一个 try/catch。 无论如何,这不应该是包罗万象的。

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

  • 所有线程的顶部(默认情况下,异常会消失得无影无踪!)
  • 在您希望永远不会退出的主处理循环中
  • 在循环内处理一个对象列表,其中一个失败不应停止其他对象
  • “主”线程的顶部——你可以控制这里的崩溃,比如当你用完内存时将一些数据转储到标准输出。
  • 如果您有一个运行代码的“Runner”(例如,如果有人向您添加了一个侦听器并且您调用了该侦听器),那么当您运行代码时,您应该捕获 Exception 以记录问题并让您继续通知其他侦听器。

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

===============>>#11 票数:1

不受欢迎的观点:并非如此。

捕获您可以从中有意义地恢复的所有错误。 有时这就是全部。

根据我的经验,异常来自哪里比实际抛出哪个异常更重要。 如果你把你的例外放在狭小的空间里,你通常不会吞下任何有用的东西。 大多数以错误类型编码的信息都是辅助信息,因此您通常最终会有效地捕获所有这些信息(但您现在必须查找 API 文档以获取可能的异常的全部集合)。

请记住,几乎在所有情况下都会出现一些异常,例如 Python 的KeyboardInterruptSystemExit 幸运的是,对于 Python 来说,它们保存在异常层次结构的一个单独分支中,因此您可以通过捕获Exception来让它们冒泡。 精心设计的异常层次结构使这种类型的事情变得非常简单。

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

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

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

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

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

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

捕捉到一般异常,感觉就像在燃烧的建筑物中拿着炸药棒,然后熄灭引信。 它会在短时间内有所帮助,但无论如何炸药都会在一段时间后爆炸。

当然,在某些情况下,可能需要捕获一般异常,但仅用于调试目的。 错误和错误应该被修复,而不是隐藏。

===============>>#15 票数: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();
    }

  ask by Triss translate from so

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