【问题标题】:How to know what exceptions to rescue?如何知道要抢救哪些异常?
【发布时间】:2012-07-23 09:35:45
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 为什么你想挽救异常?如果某个程序正在抛出它们,您究竟打算做什么来使继续处理变得有用?

标签: ruby-on-rails ruby sinatra


【解决方案1】:

一般来说(我不是 ruby​​ 程序员)我使用以下方法。

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

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

  • 需要报告吗?给来电者。我总是在主要模块或服务等自然子系统边界上执行此操作。有时(取决于 API)我可能会用“我的模块”特定的异常包装异常,以便调用者只处理我的异常。

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

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

【讨论】:

  • 关于你的第四个案例;如果您无法处理/抓住它,那也不会例外。如果你明白我的意思,试图拯救无法拯救的人是没有意义的。我的理念是异常应该是异常的,而不是程序流的产物; IE:期待异常。
  • @RussC:我不确定我是否理解你。我的第四点是关于你无法捕捉的。但是,在这种情况下,您可能需要恢复(补偿?)状态。因此我的日志记录 cmets。
【解决方案2】:

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

解决这个问题的最佳方法是在您的测试中使用带有错误 URL 的有效域,但在您的实时代码中捕获 socketError。

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

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

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

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

理想情况下,你使用的任何东西的开发者文档都应该告诉你它可以抛出什么异常。

【讨论】:

  • 在这种情况下,请求在我的控制之下。我想模拟如果该服务器关闭会发生什么。如果我确实关闭了该服务器,我也会收到一个套接字错误,因为域中没有任何东西可以接收请求和响应。
【解决方案3】:

对于源代码公开的库或 gem,您通常可以在 exceptions.rb 文件中找到异常类型。 (参考here)。否则,您将不得不依赖文档。如果一切都失败了,你可以拯救StandardError,尽管在许多情况下这不是理想的做法(参考this SO answer。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    • 2015-07-03
    • 1970-01-01
    相关资源
    最近更新 更多