嵌まった足跡満載のコード
begin
uri = URI.parse(uri_str)
http = Net::HTTP.new(uri.host, uri.port)
http.open_timeout = 5
http.read_timeout = 20
http.start do |http_local|
begin
response = http_local.get(uri.path)
if response["content-type"] =~ /image\/([^\s]+)/
ext = $1
fname = IMAGEDIR+"/#{wid}/#{id}.#{ext}"
open(fname, "w") do |w|
w.write response.body
end
end
rescue Errno::ETIMEDOUT, TimeoutError, Timeout::Error, Exception
log.puts $!.inspect
end
end
rescue Errno::ETIMEDOUT, TimeoutError, Timeout::Error, Exception
log.puts $!.inspect
end
- http.open_timeout は HTTP.start(uri) do ... の中で指定しても意味がない。startでopenされてしまうから。
- timeout の例外は素の rescue (StandardExceptionを受ける)では拾えない。で、何を投げるかnet/http のドキュメントに書かれてない。
- ドキュメントにない以上、 おすすめは "rescue Object" だ。がっかり。
- http.start はスレッドですか?
- スレッドだとして、終了までブロッキングしますか?。とか迷って http_local とかできてしまった。
- 例外が捕まらないから Thread からの例外なのかと思って迷走してしまった。
ドキュメントに載せるサンプルがいまいちなのだと思う。こんなサンプルだったら迷走せずに済んだ。
beginうーん、いや、サンプルはもっと練られていた方がうれしいな。
uri = URI.parse(uri_str)
http = Net::HTTP.new(uri.host, uri.port)
http.open_timeout = 5
http.read_timeout = 20
http.start do
response = http.get(uri.path)
do_something(response)
end
rescue Object # orz
# handle_exception
end
open_timeout とかは、HTTP.start の optional 引数(:open_timeout => 5) とかにできた方がいいな。
http.start do はもうブロックにする意味がない。すると start って名前もなんだか。
以下疑似コード。動かないけど、こんな感じであってほしかった。
begin
uri = URI.parse(uri_str)
response = Net::HTTP.get(uri.host, uri.port, :open_timeout => 5, :read_timeout =>20)
do_something(response)
rescue HTTP::TimeoutException
# handle_timeout
rescue
# handle_exception
end
0 件のコメント:
コメントを投稿