Exception handling 什么时候编写异常处理程序?

Exception handling 什么时候编写异常处理程序?,exception-handling,Exception Handling,在开发过程中,您通常在什么时候实现异常处理程序?您是在编写周围代码的同时编写它们,还是在编写代码之后再回来“强化”它 我通常会执行后一种操作,这样我就可以确切地看到我的代码失败的地方和方式,但我担心如果我马上编写异常处理程序,我的代码就没有那么有弹性了 同时,我不想花费大量的开发时间来找出当我还没有确定其他实现细节时代码可能失败的所有可能方式 我很好奇其他开发者是如何做到这一点的 更新:我只是想感谢大家的回答在开发过程中,当: 单元测试需要它 当某些表示/持久性代码需要它时 编辑 在Java

在开发过程中,您通常在什么时候实现异常处理程序?您是在编写周围代码的同时编写它们,还是在编写代码之后再回来“强化”它

我通常会执行后一种操作,这样我就可以确切地看到我的代码失败的地方和方式,但我担心如果我马上编写异常处理程序,我的代码就没有那么有弹性了

同时,我不想花费大量的开发时间来找出当我还没有确定其他实现细节时代码可能失败的所有可能方式

我很好奇其他开发者是如何做到这一点的


更新:我只是想感谢大家的回答在开发过程中,当:

  • 单元测试需要它
  • 当某些表示/持久性代码需要它时
编辑


在Java中,有时,您必须在非常早期的阶段就注意错误处理(检查异常),有时这非常烦人。

有时两者兼而有之。在某些情况下,我知道可能抛出的异常,我希望在编写代码时处理这些异常,因此我就在此时此地编写处理程序。其他时候,我不知道所有的异常,以后再通过文档、测试或两者结合来查找它们。

这是两者的结合。我知道有些事情可能会出错,比如数据库连接、配置设置、文件读/写以及功能/技术规范中的红旗。我尝试尽快为这些设置try/catch


随着应用程序随着时间的推移变得越来越大,我开始了解用户使用应用程序的方式和趋势,以及我和/或团队开发应用程序的方式和趋势,并根据需要添加这些try/catch。

这在某种程度上取决于您所从事项目的性质。在我的例子中,如果我熟悉系统的逻辑,我应该知道在哪里以及如何处理异常,甚至在编写代码之前。另一方面,我会编写我的东西,测试它,然后编写处理程序。

如果我调用API,那么我会查看可以抛出哪些异常,并根据列表来决定。可以抛出的异常通常分为以下几类:

  • 在我看来这是不可能的——请确保代码很好地失败
  • 现实的情况是,这将被抛出-如果调用,我应该怎么做
  • 确定这将根据当前输入抛出-向输入添加验证以阻止抛出
  • 我可以提出一个更相关的例外吗如果一个异常可能被调用,那么如果我提出了一个新的/不同的异常,其他调用代码是否会更清晰

总的来说,我认为在调用堆栈的高层设置catch-all-try-catch块总是一种好的做法,它可以捕获一般异常(Throwable)然后很好地向用户报告这些错误-可能会有一个界面,然后通过电子邮件将错误和stacktrace发送给开发团队,并征求用户的意见。

在我的异常处理程序中,我通常会引发更高级别的异常。例如,在Python中解析文件时,某些字符串、列表和dict操作可能会引发ValueError、IndexError或KeyError。这些异常通常对调用方没有帮助,因此我编写了一个异常处理程序,它会引发一个描述性的MyParseError。我在编写方法的同时也这样做,但后来,在编写测试时,我有时会使异常消息更加详细。

我要么立即编写异常处理程序,要么允许异常向上传播。我非常喜欢我所说的“你以后不会回去修理它的,是吗?”原则。你说你会的,但老实说,一旦你让它工作起来,你就不会回去修理它了,是吗?现在就去拿!立即编写异常处理程序,或者添加一个
throws
子句,使其成为其他人的问题。现在就做正确的事情

但你知道吗,有时候你不能。无论您做什么,都不要使用空异常处理程序吞咽异常!这是邪恶的:

try {
    connection.close();
}
catch (Exception e) {
    // TODO Auto-generated code
}
我会踢我队中任何一个检查过的人

如果您真的不知道如何处理异常,并且无法添加
throws
子句来向上传播异常,那么至少要做一些事情。如果没有其他内容,则打印堆栈跟踪。这并不理想,但至少你没有隐瞒错误

catch (IOException exception) {
    exception.printStackTrace();
}
通过应用程序的日志记录系统记录它会更好,尽管您不应该养成这样的习惯。处理这类事情应该是打电话的人的责任

catch (IOException exception) {
    log.error(exception, "Unable to open configuration file %s.", fileName);
}
作为最后一种手段,您可以通过将异常包装在
RuntimeException
中来结束运行
throws
子句。至少你给了呼叫链上更高层的人一个处理错误的机会,这通常是正确的做法

catch (IOException exception) {
    throw new RuntimeException(exception);
}

我的方法是立即处理异常处理,因为它不是可以愉快地推迟的无目的的负担


只要处理在编写代码时应用的异常,传播所有无关紧要的异常,然后再回来修复任何损坏的异常,就可以为您节省很多眼泪。

通常,我不仅在编写代码时编写异常处理,但我首先尝试编写代码以避免异常。优点是,如果我知道我需要处理一个异常,我会记得去处理,如果我能避免一个总是有利的异常。在编写代码之后,我还使用边界条件测试代码,以查看是否有任何可能遗漏的异常

我想在编写实际代码时编写处理程序是最好的习惯