抛出新异常vs将消息写回用户(避免异常)

时间:2010-01-25 22:16:25

标签: language-agnostic exception-handling

如果参数不是正确的形式,或者其他什么,我看到很多代码写入抛出异常的地方。基本上“扔新......”。

这有什么好处?通过检查参数可以避免异常(例如,如果为null,则将消息写回webpage / winform)。当异常很昂贵时,为什么不使用这种方法?

由于

8 个答案:

答案 0 :(得分:10)

这里有几点值得一提:

  • 首先,您认为异常费用昂贵的假设通常是不真实的 - 例外情况是......非常......它们不应经常发生,以对程序性能产生任何有意义的影响。如果你看到足够的例外情况表明性能是个问题,那么你可以吃更大的鱼。

  • 其次,编写良好的类,函数或模块程序应该能够稍微优雅地检测和处理无效输入。它有助于代码的维护者和调试者将问题定位为关闭尽可能地介绍他们。如果不检查参数,它们通常会在代码中导致失败 - 远离实际错误。调试这些问题可能非常痛苦。

  • 第三,您假设所有代码都知道执行它的上下文。方法可能深入到框架或库中,并且不知道它是否正在运行在Web应用程序,控制台应用程序,NT服务等等。此外,在代码的整个部分显示有关无效参数的信息是一种可怕的做法 - 应该集中控制责任 - 否则你的UI很容易变成一堆错误穿插着实际的演示内容。

  • 最后,异常允许程序有时处理并从问题中恢复而不是将其暴露给用户。不要通过在错误发生时立即直接显示错误来降低此功能。现在,被授予,通常无效的参数是编程缺陷的症状(而不是环境或配置问题) - 因此在大多数情况下它们无法处理。但是,有时它们可​​以被处理。

答案 1 :(得分:4)

例如,如果您正在编写要由您不知道或不存在的代码使用的库,那么如何处理该错误取决于进行调用的代码。

因此抛出异常是很自然的事情。允许您决定如何将该错误方案处理给调用者/使用者。

答案 2 :(得分:2)

抛出异常:

  • 让其他程序员明白情况异常
  • 允许软件调用所涉及的方法来清楚地处理问题
  • 显示工具和编译器,情况非常特殊,以便他们可以协助程序员
  • 允许将信息传递给异常对象本身的处理例程

打印字符串 - 好吧 - 不是,真的。

就例外的“费用”而言,例外只应在特殊情况下抛出,即很少并且作为处理错误的一部分 - 我个人没有遇到过例外的'费用'的情况问题。在this question中有关于这一点的更多讨论。

答案 3 :(得分:1)

这称为按合同设计

契约式设计的基本思想是对象之间有契约,如果调用者不履行契约,则接收者应该以异常失败而不是试图猜测呼叫者的意图。在一天结束时,这会导致更稳定的软件(特别是当不止一个人在项目上写作时,从那时起合同也成为程序员之间的合同)。

PS: 经常被遗忘的合同设计的一个重要问题如下。它必须才能使客户知道它是否履行合同。例如,如果堆栈的合同是客户端只有pop当堆栈不为空时,那么必须是一个isEmpty方法来检查它,客户端应该使用它调用pop之前的方法。因此,这就是为什么使用契约式设计的代码混乱的例外情况仍然会被抛出。

答案 4 :(得分:0)

一般而言,语言 - 从语言上讲,异常是昂贵的,这是不正确的假设。这取决于很多因素。

通常,异常是发出错误信号的通用方式,它独立于任何形式的表示。发送带有错误消息的页面会使错误报告与UI的呈现过于紧密耦合。在灵活和可扩展的设计方面,这通常不是一个好主意。

问题是一般性和语言无关,因此答案不会深入细节。

顺便说一下,根据编程语言,错误处理的设计以及其他因素的数量,方法可能会有所不同。但是,了解各种选项是个好主意:

  

不要太担心什么()   信息。有消息很高兴   一个程序员有机会   弄清楚,但你不太可能   能够撰写相关的和   用户可理解的错误消息   抛出异常的点(...)

考虑到上述指导原则,经过一段时间的考虑,不清楚这样的错误网页应该显示什么,信息级别,非常技术性或更加用户友好。使用异常,它可以在系统的各个级别提供更大的灵活性,作为当您需要处理时(<显示错误)捕获的规则之一,否则忽略

答案 5 :(得分:0)

如果将代码编译到库中并在多个应用程序中重用,最好抛出异常。在这种情况下,调用库的客户端应该适当地处理异常并报告用户友好的消息。

答案 6 :(得分:0)

我抛出异常有两个主要原因,而不是将错误消息写入标准输出。

  1. 调试更容易 - 我知道程序是否因为错误而退出。此外,由于Java中的异常可以被子类化,我确切地知道发生了什么类型的错误。

  2. 如果您编写API,然后决定需要GUI前端,也许您希望将这些异常显示在消息对话框中,而不是将它们写入标准输出。

    < / LI>

答案 7 :(得分:0)

在大多数环境中,例外情况比编写到控制台的内容更容易编写测试:

it "should reject a negative initial balance" do
  Account.new(-1).should raise_error(ArgumentError, "Invalid balance: -1")
end