21

这是一个有点宽泛的问题,但它是我在使用 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通过查看代码和测试所学到的知识?

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

4

5 回答 5

9

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

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

于 2009-09-08T07:30:06.743 回答
4

如果您想丢弃无效的 JSON 数据:

begin
  res = JSON.parse(string)
rescue JSON::ParserError => e
  # string was not valid
end
于 2015-08-25T12:43:18.310 回答
3

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

begin
   # code goes here
rescue
   # fail reason is in $!
end
于 2009-09-08T08:31:03.763 回答
1

您永远无法确定会引发哪些异常,除非库代码捕获所有异常然后包装它们。您最好的选择是通过清理输入的内容来假设您的代码输入良好,然后使用您自己的更高级别的异常处理来捕获输入中的错误输入。

于 2009-09-08T07:18:45.787 回答
0

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

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

如果源代码不可用或无法轻松访问,则文档是您的下一个最佳信息来源。这就引出了你的第二个问题。不幸的是,即使在标准库中,文档也没有关于潜在异常的一致格式。例如,Net::Http文档并没有明确说明哪些异常可用,尽管如果您仔细研究它,您会发现所有异常都继承自Net::HTTPExceptions.

作为另一个示例(再次来自标准库文档),JSON文档显示了一个Exception(它确实在exceptions.rb文件中,尽管在json/lib/json/add/exceptions.rb的源代码中)。这里的关键是它是不一致的。该类的文档Exception没有以类似于Net::HTTPException.

此外,在大多数方法的文档中,都没有指出可能引发的异常。参考例如parse,已经提到的模块最常用的方法之一JSON:根本没有提到异常。

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

等等等等。

网络搜索会找到很多关于如何挽救异常的信息,甚至是多种类型的异常(参考这里这里这里这里等)。但是,这些都不能回答您的问题,即查找可以引发的异常的标准是什么,以及相关文档在哪里

最后一点,这里建议如果一切都失败了,你可以救援StandardError。在许多情况下,这是一个不太理想的做法(参考这个 SO answer),尽管我假设您已经根据您对 Java 的熟悉程度和您提出这个问题的方式理解了这一点。当然,来自 Java 世界,您需要记住要救援StandardError而不是Exception.

于 2020-05-05T11:57:12.910 回答