Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 什么&x2019;处理Net::HTTP异常的最佳方法是什么?_Ruby - Fatal编程技术网

Ruby 什么&x2019;处理Net::HTTP异常的最佳方法是什么?

Ruby 什么&x2019;处理Net::HTTP异常的最佳方法是什么?,ruby,Ruby,从Net::HTTP拯救异常的最佳方法是什么 Ruby的socket.c中描述了抛出的异常,如Errno::ETIMEDOUT、Errno::ECONNRESET和Errno::econnrefered。所有这些的基类都是SystemCallError,但编写如下代码感觉很奇怪,因为SystemCallError似乎离调用HTTP很远: begin response = Net::HTTP.get_response(uri) response.code == "200" rescue S

从Net::HTTP拯救异常的最佳方法是什么


Ruby的
socket.c
中描述了抛出的异常,如
Errno::ETIMEDOUT
Errno::ECONNRESET
Errno::econnrefered
。所有这些的基类都是
SystemCallError
,但编写如下代码感觉很奇怪,因为
SystemCallError
似乎离调用
HTTP
很远:

begin
  response = Net::HTTP.get_response(uri)
  response.code == "200"
rescue SystemCallError
  false
end

只是我吗?除了修复
Net::HTTP
来处理可能弹出的
Errno
异常并将它们封装在父
HttpRequestException
中之外,还有更好的方法来处理这个问题吗?

我同意,处理所有潜在的异常绝对是一件痛苦的事情。请看以下示例:

使用
Net::HTTP
可能会很痛苦。它有大约40种不同的方式 可以执行任何一项任务,并且可以抛出大约50个异常

为了对谷歌的热爱,以下是我为“正确的方式”所做的 捕获Net::HTTP可能向您抛出的任何异常:

begin
  response = Net::HTTP.post_form(...) # or any Net::HTTP call
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
       Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
  ...
end
为什么不干脆
rescue Exception=>e
?这是一个坏习惯,就像 它隐藏了实际代码中的任何问题(比如语法错误、抱怨) 零等)。当然,如果可能的话,这一切都会容易得多 错误有一个共同的祖先

我在处理Net::HTTP时遇到的问题让我 不知道写一个新的HTTP客户端库是否值得。 一个更容易在测试中模仿的模型,并且没有所有这些 丑陋的小面

我所做的,也看到大多数人所做的,是从Net::HTTP转移到第三方HTTP库,例如:


你的直觉是正确的,对于最强大的解决方案,我可能会单独(或以小组形式)拯救每一个人,并采取适当的行动,比如再次尝试连接,或者一起放弃请求。我喜欢避免使用非常高级/通用的rescue,因为它可能捕获我没有准备好或没有预料到的异常。

我也遇到了同样的问题,经过大量研究,我意识到处理Net::HTTP方法引发的所有异常的最佳方法是从StandardError中拯救


正如所指出的,他建议从许多例外中拯救出来,但这仍然是一个缺陷。有一些他无法挽救的异常,如
Errno::ehostureach
Errno::econnrefered
,以及一些可能的
socket
异常

因此,正如我在中所发现的,最好的解决方案是从
标准错误中解救出来,不幸的是:

begin
  response = Net::HTTP.get_response(uri)
rescue StandardError
  false
end

这很糟糕,但如果您希望系统不会因为这些其他异常而中断,请使用此方法。

另一种方法是将所有这些异常聚合到一个常量中,然后重新使用此常量,例如:

ALL_NET_HTTP_ERRORS = [
  Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
  Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError
]

begin
  your_http_logic()
rescue *ALL_NET_HTTP_ERRORS
  …
end
它更易于维护和清洁


然而,警告的字眼。我从前面提到的Tammer Saleh的博客文章中复制了可能的例外列表,我知道他的列表是不完整的。例如,
Net::HTTP.get(URI(“wow”)
引发未列出的
Errno::econnreference
。此外,如果列表应该针对不同的Ruby版本进行修改,我也不会感到惊讶


因此,我建议在大多数情况下坚持使用
rescue StandardError
。为了避免捕获过多,请尽可能多地移动到begin rescue end块之外,最好只保留对
Net::HTTP
方法之一的调用。

或Ruby自己的或。openuri是一个简单得多的快速任务接口。HTTPClient和Typhous具有工业实力,能够处理线程和各种其他繁重的工作。
HTTPClient
非常热门!我想我以后会用这个。谢谢你的推荐。你的谷歌fu非常优秀,我很高兴能找到Tammer的作品。这正是我想要的。
Errno::econnrefered
值得包括在内。请参阅Unix基础系统的错误列表谢谢大家!最后,我将答案打包成一个Ruby Gem的形式,我可以在将来使用它来处理这种情况:net_http_exception_fix[正确链接:(Edward的评论在URL中附加了一个“]”)。我还编写了另一个库,它以不同的方式解决了同样的问题:酷!干得好,Henrik。“net_http_exception_fix”无法捕获Errno::EHOSTUNREACH。但它仍然值得使用。好吧,酷-很高兴知道我不是唯一一个:)我最终将你的建议+@MikeLewis打包成一个名为net_http_exception_fix的宝石,我喜欢这个答案。这被低估了。