【问题标题】:ruby catch connection timeout errorruby catch 连接超时错误
【发布时间】:2013-12-20 08:59:03
【问题描述】:

我正在使用 Ruby 中的 Mechanize 将表单发布到站点以获取数据。偶尔会报错

too many connection resets (due to Operation timed out - Errno::ETIMEDOUT) after 13 requests on 34234234234242, last used 20.518373 seconds ago

这会使服务器崩溃。我想抓住这个错误并处理它(稍后重试)。

我试过了

 begin 
    postForm(form)
  rescue Errno::ETIMEDOUT
    puts "=====>TimeOut ERROR!:"  
  end

但它没有捕捉到错误。 我错过了什么?

谢谢。

【问题讨论】:

  • 尝试再放一个救援异常=>e

标签: ruby ruby-on-rails-3 mechanize


【解决方案1】:

看起来 Mechanize 捕获了 Errno::ETIMEDOUT 错误并抛出了一个包含错误消息的新异常。所以异常类名不同,不能用Errno::ETIMEDOUT捕获。

要确定错误的类型,试试这个:

begin 
  postForm(form)
rescue => e
  puts e.class  
end

这将为您提供异常类名称,您可以更新救援子句。

【讨论】:

  • 这不会捕获所有异常,而只会捕获从StandardError 继承的异常。最好使用rescue Exception => e
  • @NafaaBoutefer 捕获Exception 被认为是不好的做法,因为它会破坏某些行为(如信号、Ctrl-C 等)并且可能会导致您的程序在有充分理由的情况下继续运行应该停止。如果您需要捕获一个不是从StandardError 继承的特定异常,最好直接指定它。
  • 是的,没错。所以如果它是一个信号,你可以再次引发异常。 raise e if e.is_a?(Interrupt)
  • 好的,信号只是一个例子。有很多您绝对不想捕获的异常,包括NoMemoryErrorSyntaxErrorLoadErrorSystemStackError。见ruby-doc.org/core-2.2.0/Exception.html
  • 我的评论是根据你自己的回答。您想捕获所有异常只是为了了解导致该问题的异常类。对于这个捕捉Exception 是最好的方法。这是因为所有异常都继承自它。但是您建议的方式不会捕获某些异常。一旦知道了要处理的异常列表,就可以将它们放入数组中并以rescue *exceptions_array => e 的方式处理它们。
【解决方案2】:

如果您阅读了整个错误消息,您会发现失败是因为“连接重置次数过多”:超时只是导致连接重置 13 次的原因,并且已经被抢救。

所以如果你阅读Net-Http-persistent>here<的源码,你会看到你需要捕捉的错误是:

Net::HTTP::Persistent::Error

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    • 2013-05-29
    • 2013-03-30
    • 2017-07-12
    • 1970-01-01
    相关资源
    最近更新 更多