9

ruby (1.8.6) で「open-uri」を使用してリンクのリストからコンテンツを処理しようとしていますが、1 つのリンクが壊れているか認証が必要な場合にエラーが発生すると、悪いことが起こります。

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 のサブクラスです。したがって、rescue => 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 に答える