9

我正在尝试使用 ruby​​ (1.8.6) 中的“open-uri”处理链接列表中的内容,但是当一个链接断开或需要身份验证时出现错误时,就会发生坏事:

open-uri.rb:277:in `open_http': 404 Not Found (OpenURI::HTTPError)
from C:/tools/Ruby/lib/ruby/1.8/open-uri.rb:616:in `buffer_open'
from C:/tools/Ruby/lib/ruby/1.8/open-uri.rb:164:in `open_loop'
from C:/tools/Ruby/lib/ruby/1.8/open-uri.rb:162:in `catch' 

或者

C:/tools/Ruby/lib/ruby/1.8/net/http.rb:560:in `initialize': getaddrinfo: no address associated with hostname. (SocketError)
from C:/tools/Ruby/lib/ruby/1.8/net/http.rb:560:in `open'
from C:/tools/Ruby/lib/ruby/1.8/net/http.rb:560:in `connect'
from C:/tools/Ruby/lib/ruby/1.8/timeout.rb:53:in `timeout'

或者

C:/tools/Ruby/lib/ruby/1.8/net/protocol.rb:133:in `sysread': An existing connection was forcibly closed by the remote host. (Errno::ECONNRESET)
from C:/tools/Ruby/lib/ruby/1.8/net/protocol.rb:133:in `rbuf_fill'
from C:/tools/Ruby/lib/ruby/1.8/timeout.rb:62:in `timeout'
from C:/tools/Ruby/lib/ruby/1.8/timeout.rb:93:in `timeout'

有没有办法在处理任何数据之前测试响应(url)?

代码是:

require 'open-uri'

smth.css.each do |item| 
 open('item[:name]', 'wb') do |file|
   file << open('item[:href]').read
 end
end

非常感谢

4

2 回答 2

24

你可以尝试一些类似的东西

    require 'open-uri'

    smth.css.each do |item|
     begin 
       open('item[:name]', 'wb') do |file|
         file << open('item[:href]').read
       end
     rescue => e
       case e
       when OpenURI::HTTPError
         # do something
       when SocketError
         # do something else
       else
         raise e
       end
      rescue SystemCallError => e
       if e === Errno::ECONNRESET
        # do something else
       else
        raise e
       end
     end
   end

我不知道有任何方法可以在不打开连接并尝试的情况下测试连接,因此拯救这些错误将是我能想到的唯一方法。需要注意的是 OpenURI::HTTPError 和 SocketError 都是 StandardError 的子类,而 Errno::ECONNRESET 是 SystemCallError 的子类。所以救援 => e 不会捕获 Errno::ECONNRESET。

于 2011-08-24T04:19:22.390 回答
0

我能够通过使用条件 if/else 语句检查“失败”操作的返回值来解决此问题:

def controller_action
    url = "some_API"
    response = open(url).read
    data = JSON.parse(response)["data"]
    if response["status"] == "failure"
        redirect_to :action => "home" 
    else
        do_something_else
    end
end
于 2012-12-13T19:56:25.297 回答