4

在使用 Ruby 中的特定代码库时,我经常发现自己不知道要挽救哪些异常。

例如,我经常对我的 rails/sinatra 应用程序发出的任何 HTTP 请求使用 HTTParty。我挖掘了 HTTParty 的代码,发现了一个包含所使用的已定义异常的文件。伟大的!我会在提出请求时拯救他们。

为了测试它,我为请求输入了一个虚假的域名,但是我没有预料到 HTTParty::ResponseError 异常,而是得到了一个 SocketError 异常。

处理这个问题的最佳方法是什么?我知道 HTTParty 是 Ruby 实现的包装器,这可能是引发 SocketError 异常的原因。但我通常怎么知道呢?

我可以通过拯救“异常”来解决这个问题,但这是非常糟糕的做法。我宁愿很清楚我可能导致的异常并处理这些异常。

编辑:我应该澄清一下,真正促使我提出这个问题的是,我不知道如何找出调用特定函数时可能引发的异常......也就是说,无需查看每一个函数调用在堆栈中。

4

3 回答 3

6

一般来说(我不是红宝石程序员)我使用以下方法。

我通过以下方式处理异常:

  • 我可以从中恢复吗? 如果异常可能发生并且我知道我可以恢复或重试,那么我处理异常。

  • 是否需要报告? 如果异常可能发生,但我知道我可能无法恢复或重试,那么我通过记录异常来处理异常,然后将其传递给调用者。我总是在主要模块或服务等自然子系统边界上执行此操作。有时(取决于 API)我可能会用“我的模块”特定的异常包装异常,以便调用者只处理我的异常。

  • 不能处理吗?所有未处理的异常都应在顶层捕获并(a)报告,(b)确保系统保持稳定和一致。无论其他两个是否完成,这是应该始终存在的。

当然还有另一类例外 - 那些非常严重以至于他们没有机会处理它们的例外。对于这些,只有一种解决方案——事后调试,我发现最好的办法是日志、日志和更多日志。并且在从小到大的许多系统上工作过,我宁愿为了稳定性和可恢复性而牺牲性能(除非它很关键),并添加大量的日志记录——如果可能的话,自省。

于 2012-07-25T01:46:04.907 回答
0

如果你输入一个伪造的域名,socketError 响应是完全可以的。毕竟 - 尝试连接到不存在的域会导致连接失败 AKA SocketError。

处理这个问题的最好方法是在你的测试中使用一个带有错误 URL 的有效域,但在你的实时代码中捕获 socketError。

这里的问题不是你捕捉到了错误的异常,而是你用错误的数据来启动测试。

最好的做法是了解可能发生的异常并管理它们,当我说了解时,我正在理解 - URL 来自哪里,它是由您的用户输入的吗?如果是这样,永远不要相信它并抓住一切。它是否来自您的配置数据?半信任它并记录错误,除非 URL 正常是关键任务。

这里没有正确或错误的答案,但我希望这种方法会给你一个好的结果。

编辑:我在这里试图做的是倡导程序员的思维方式,即意识到他们的行为结果。我们都知道尝试连接到 'thisServiceIsTotallyBogus.somethingbad.notAvalidDomain' 会失败;但是程序员的心态应该是首先验证该域的确切来源。如果它是由用户输入的,那么您必须承担全部检查;如果您知道它来自仅由您自己或您的支持团队访问的配置文件;你可以放松一点;可悲的是,这是一个不好的例子,因为您应该始终测试 URL,因为有时互联网无法正常工作!

理想情况下,您使用的任何东西的开发人员文档都应该告诉您它可以抛出哪些异常。

于 2012-07-25T01:43:58.920 回答
0

对于源代码公开可用的库或 gem,您通常可以在exceptions.rb文件中找到异常类型。(参考这里)。否则,您将不得不依赖文档。如果所有其他方法都失败了,您可以进行救援StandardError,尽管在许多情况下这是一种不太理想的做法(参考这个 SO answer

于 2020-05-05T01:19:28.240 回答