From: irodori@... Date: 2008-02-22T17:37:18+09:00 Subject: [ruby-list:44680] Re: beginで捉えられないエラー?? 本庄と申します。 At Fri, 22 Feb 2008 14:02:31 +0900, Kabu and Ruby管理人 wrote: > KirbyBaseというデータベースに株価データを取り込むようにしたのですが、最初のうちは順調に取り込んでいますが、以下のようなエラーが出てしまいます。 > 全体をbegin ... rescue ... endで括ったりしたのですが、やはりエラーが出てしまいます。 > ライブラリからのエラーのようですが、どういう意味でしょうか? とほほ、、。 エラーの直接の原因については追っていないので分かりませんが、例外につい ては下記の理由によるものです。 Timeout::Error は Interrupt を継承しているので、元は SignalException になります。 rescue は捕捉する例外を明示しない場合、StandardError を捕捉するように なっていますので、この場合例外はキャッチされず、**正しく**落ちます。 タイムアウトを捕捉したい場合は、 begin ... rescue Timeout::Error puts 'timeout error' end のようにします。 何故タイムアウト例外が発生するのかについては、そのときの各変数の値 (特 に URI) がわからないと何とも言えません。 # 再現するには fetch する数が多すぎるので… その他いくつか気になった点です。 > 9350.downto(5000) do |meigara| 頻繁にwebサーバにアクセスしているようなのでリクエストの間には sleep を はさんだほうが良いと思います。 > puts "#{meigara}のデータ取得を開始します。" meigara を数値として使っているところはないので to_s で最初に文字列に した方が全体的にすっきりすると思います。 > begin > Dir::chdir( storedir ) > rescue > puts "#{storedir}は存在しません。作成します。" > Dir::mkdir( storedir ) > Dir::chdir( storedir ) > end 先に chdir をして例外をキャッチするのではなく FileTest.exist? や FileTest.directory? を使うべきです。 > begin > f = open( yahoourl ) > rescue > puts 'タイムアウトです。再試行します。' > retry > end 例外をキャッチしたらもれなく retry していますが、恒常的なエラーの場合 には無限ループになります。上限を設けるか、落ちるにまかせた方が良いと思 います。また、同一ホストへのリクエストが連続する場合は sleep も忘れずに。 > if line.scan(/#{yahooformat}/) != [] > str.push line.scan(/#{yahooformat}/) > end yahooformat は Regexp のインスタンスなので // で囲む必要はありません。 また、後でもう一度 scan するのは無駄なので、1度だけにして結果を代入し ておきましょう。 -- Eiji Honjoh