这是一个广泛的问题,但在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
的内容?
(我还编辑了这个例子来澄清它是我正在解析的服务器的响应。)
答案 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 的大量信息,以挽救异常,甚至可以挽救多种类型的异常(参见here,here,here ,here等)。但是,这些都不是您对以下问题的答案:什么是查找可能引发的异常的标准,而其中是此问题的文档。
作为最后的提示,此处建议如果所有其他方法都失败,则可以营救StandardError
。尽管我假设您已经基于对Java的熟悉程度和提出此问题的方式,但在很多情况下,这不是理想的做法(参考this SO answer)。当然,来自Java世界,您需要记住rescue StandardError
and not Exception
。