如何处理不知道Ruby中的库方法可以引发什么异常?

时间:2009-09-08 07:15:18

标签: ruby exception exception-handling rescue

这是一个广泛的问题,但在Ruby编程时我会继续遇到这个问题。我来自一个很大的C和Java背景,当我使用库函数或方法时,我会查看文档并查看错误返回的内容(通常在C中)或它可以抛出的异常(在Java中)。

在Ruby中,情况似乎完全不同。刚才我需要解析一些从服务器收到的JSON:

data = JSON.parse(response)

当然,在编写此代码后,我想的第一件事是,如果输入不好怎么办? parse是否会因错误返回nil,或者引发一些异常,如果是,那会是哪些?

我查看了文档(http://flori.github.com/json/doc/JSON.html#M000022)并简单地看到了:

“将JSON字符串源解析为Ruby数据结构并返回它。”

这只是我在Ruby中反复遇到的模式的一个例子。最初,我认为这是我正在使用的任何库的文档的一些缺点,但现在我开始觉得这是标准的做法,我的思维方式与Ruby程序员有点不同。是否有一些我不知道的惯例?

开发商如何处理这个问题?

(是的,我确实查看了库方法的代码,并且可以了解引发了什么异常,但我不能100%确定,如果没有记录,我会感到不舒服依赖它。)

编辑:在查看前两个答案后,让我继续上面的JSON解析示例。

我怀疑我不应该这样做:

begin
  data = JSON.parse(response)
  raise "parse error" if data.nil?
rescue Exception => e
  # blahblah
end

因为我可以查看代码/测试并看到它似乎引发错误ParserError(返回nil似乎不是Ruby中的标准做法)。我说推荐的做法是否正确:

begin
  data = JSON.parse(response)
rescue JSON::ParserError => e
  # blahblah
end

...基于我通过查看代码和测试了解ParserError的内容?

(我还编辑了这个例子来澄清它是我正在解析的服务器的响应。)

5 个答案:

答案 0 :(得分:9)

  

(是的,我确实查看了库方法的代码,并且可以了解引发了什么异常,但我不能100%确定,如果没有记录,我会感到不舒服依赖它。)

我建议看一下测试,因为它们会显示一些“可能的”场景以及可能会引发的内容。不要忘记,好的测试也是文档。

答案 1 :(得分:4)

我想如果没有提供文档,你必须依赖这样的东西:

begin
   # code goes here
rescue
   # fail reason is in $!
end

答案 2 :(得分:4)

是否要丢弃无效的JSON数据:

begin
  res = JSON.parse(string)
rescue JSON::ParserError => e
  # string was not valid
end

答案 3 :(得分:2)

你永远不能确定可以引发什么异常,除非库代码捕获所有异常然后包装它们。最好的办法是通过清理代码来假设代码提供良好的输入,然后使用自己的更高级异常处理来捕获输入中的错误输入。

答案 4 :(得分:0)

您的问题基本上可以归结为两个问题:是否有用于查找可能的例外的约定或标准,以及与该约定相关的文档在哪里?

对于第一个问题,最接近约定或标准的是 exceptions.rb 文件的位置和存在。对于公开提供源代码的库或gem,通常可以在此文件中找到异常类型。 (请参阅here)。

如果没有源代码或无法轻松访问源代码,则文档是您的下一个最佳信息来源。这将我们带到您的第二个问题。不幸的是,即使在标准库中,文档也没有关于潜在异常的一致格式。例如,Net::Http documentation并没有明显表明可以使用哪些例外,但是如果您仔细研究,则会发现所有例外inherit from Net::HTTPExceptions

作为另一个示例(同样来自标准库文档),JSON documentation显示了一个Exception class(确实位于 exceptions.rb 文件中,尽管在源中位于 json / lib / json / add / exceptions.rb )。这里的重点是不一致。 Exception类的文档未以类似于Net::HTTPException的方式列出。

此外,在大多数方法的文档中,没有迹象表明可能会引发异常。例如,请参考parse,这是JSON模块中最常用的方法之一:根本没有提到异常。

在核心模块中也发现缺乏标准和一致性。 Documentation for Math不包含对 exceptions.rb 文件的任何引用。与File及其父IO相同。

等等,依此类推。

通过网络搜索,可以找到有关 how 的大量信息,以挽救异常,甚至可以挽救多种类型的异常(参见herehereherehere等)。但是,这些都不是您对以下问题的答案:什么是查找可能引发的异常的标准,而其中是此问题的文档。

作为最后的提示,此处建议如果所有其他方法都失败,则可以营救StandardError。尽管我假设您已经基于对Java的熟悉程度和提出此问题的方式,但在很多情况下,这不是理想的做法(参考this SO answer)。当然,来自Java世界,您需要记住rescue StandardError and not Exception