LWP::UserAgentのtimeoutエラー判定法 (Can't connect to (connect: timeout)を出力してる場所のメモ)
LWP::UserAgentでtimeoutをセットしたときに、
「timeout」と「それ以外のエラー」を判別したい。
以下のようなコードを見つけたのだが、
use LWP::UserAgent; use XML::TreePP; my $ua = LWP::UserAgent->new(); $ua->timeout(3); my $tpp = XML::TreePP->new(); $tpp->set(lwp_useragent => $ua); my ($tree, $xml, $code) = $tpp->parsehttp(GET => 'http://d.hatena.ne.jp/favril/rss'); # 本当はAPIのリクエストURLとか if ( $code == 200 ) { print "取得成功\n"; } elsif ( ($code == 500) && ($xml =~ /\(connect: timeout\)/) ) { print "タイムアウト\n"; } else { print "タイムアウト以外のエラー"; }
タイムアウトを判定している "(connect: timeout)" なる文字列が、
一体どこで出力されているのか簡単には辿り着けず(orz)、
この判定法が一般的に使えるのかどうか迷ったのでメモ*1。
XML::TreePPを探しても、LWP::UserAgentを探しても、
そんな文字列は見当たらなかったので困ったが、
結論から言うと、以下にあった。
LWP::Protocol::http.pm
my $sock = $self->socket_class->new(PeerAddr => $host, PeerPort => $port, Proto => 'tcp', Timeout => $timeout, KeepAlive => !!$conn_cache, SendTE => 1, $self->_extra_sock_opts($host, $port), ); unless ($sock) { # IO::Socket::INET leaves additional error messages in $@ $@ =~ s/^.*?: //; die "Can't connect to $host:$port ($@)"; }
LWP::UserAgentの中で見るとたぶんここ。
LWP::UserAgent.pm
if (!$response && $self->{use_eval}) { # we eval, and turn dies into responses below eval { $response = $protocol->request($request, $proxy, $arg, $size, $self->{timeout}); }; if ($@) { $@ =~ s/ at .* line \d+.*//s; # remove file/line number $response = _new_response($request, &HTTP::Status::RC_INTERNAL_SERVER_ERROR, $@); } }
ということで、LWP::UserAgentを使ってる分には、
上に書いた判定方法でたぶん問題ない。
-
-
- -
-
ちなみに、上記のタイムアウトは、接続時点のタイムアウトで、
接続はできたけど、データを受信し切れなかったとかだと、「500 read timeout」になるのかな?
エラーメッセージ作ってるのは以下。
LWP::Protocol::http.pm
if (my $timeout = ${*$self}{io_socket_timeout}) { die "read timeout" unless $self->can_read($timeout); }