require 'open-uri' require 'resolv-replace' require 'timeout' TIMEOUT = 3 begin timeout(TIMEOUT) do open(url) do |f| # 処理 end end rescue TimeoutError => e # タイムアウト時の例外処理 rescue => e # その他の例外処理 end
- timeout による割り込みはRubyのThreadによって実現されており、C言語レベルで実装されRuby のスレッドが割り込めない処理では無効なので、SocketでDNSの名前解決に時間がかかった場合にタイムアウトしない。そのため、resolvライブラリを使うようにresolv-replaceでメソッドの書き換えを行う。
- タイムアウト時のTimeoutErrorはStandardErrorのサブクラスではないので、捕捉するためには明示的に捕捉するクラス(TimeoutError)をrescueに指定する必要がある。