From: Mitsuru Ogino Date: 2003-08-11T21:16:11+09:00 Subject: [ruby-list:38080] ポートが閉じているときの例外など 荻野と申します。いつも質問や要望ばかりですみません。 Ruby 1.6.8 において net/smtp や net/pop を使用させていただいていますが、 サーバがポートを開いていなかったときに発生する例外が、ちょっとわかりづ らく感じました。もし、可能であれば将来のバージョンでは修正していただけ るとうれしいです。 自分でパッチを提案できれば良いのですが、私の技量ではそもそも net/protocol.rb で対処すべき問題なのかどうかすらわかりませんでした。 # 1.8.0 で修正済みでしたらすみません。 $ telnet 192.168.0.1 smtp (snip) 220 xxx.xxx.xxx ESMTP Postfix quit 221 Bye $ telnet 192.168.0.2 smtp Trying 192.168.0.2... telnet: connect to address 192.168.0.2: Connection refused telnet: Unable to connect to remote host $ ruby -v ruby 1.6.8 (2003-03-26) [i386-freebsd5] のとき、 $ ruby -r net/smtp -e 'Net::SMTP::start("192.168.0.1") { |smtp| }' $ (エラーなしで終了) ですが、ポートが閉じているときは、Invalid argument - "connect(2)" (Errno::EINVAL) と表示されます。 $ ruby -r net/smtp -e 'Net::SMTP::start("192.168.0.2") { |smtp| }' /usr/local/lib/ruby/1.6/net/protocol.rb:468:in `new': Invalid argument - "connect(2)" (Errno::EINVAL) from /usr/local/lib/ruby/1.6/net/protocol.rb:468:in `connect' from /usr/local/lib/ruby/1.6/net/protocol.rb:467:in `timeout' from /usr/local/lib/ruby/1.6/net/protocol.rb:467:in `connect' from /usr/local/lib/ruby/1.6/net/protocol.rb:449:in `initialize' from /usr/local/lib/ruby/1.6/net/protocol.rb:149:in `new' from /usr/local/lib/ruby/1.6/net/protocol.rb:149:in `conn_socket' from /usr/local/lib/ruby/1.6/net/smtp.rb:237:in `do_start' from /usr/local/lib/ruby/1.6/net/protocol.rb:131:in `start' from /usr/local/lib/ruby/1.6/net/protocol.rb:71:in `start' from -e:1 net/pop でも同様になります。 確かに引数が違っているとも言えなくはないのですが、ProtocolError のサブ クラスを返してもらえると、私のように面食らう人間が減りそうですのでご検 討いただければと思い、メールを出させていただきました。 もう一つ、比較的小さな要望としましては、サーバが応答しない場合、 $ ruby -r net/smtp -e 'Net::SMTP::start("192.168.0.3") { |smtp| }' /usr/local/lib/ruby/1.6/timeout.rb:37:in `connect': execution expired (TimeoutError) from /usr/local/lib/ruby/1.6/net/protocol.rb:467:in `timeout' (以下略) と TimeoutError が返りますが、これも使用する側で timeout.rb を使用して いるときに混乱になりますので、 ライブラリで timeout.rb を使う場合は、ユーザが指定した timeout を 捕捉しないように、ライブラリ内では TimeoutError のサブクラスを定義 して使用した方が無難です。 と推奨(?)されているように、サブクラスを返していただけると助かるよう に思います。(ProtoNoResponseError or ProtoTimeoutOnConnectError とか、 読み出し時の TimeoutError と区別できるとなおうれしい…) # 個人的には接続時のエラーは ProtocolError のサブクラスの方が使いやす # いようにも思うのですが、よくわかりません。 しかし grep で require 'timeout' を/usr/local/lib/ruby/1.6/ 以下で検索 しても、該当する以下の標準添付ライブラリ全部で、特に TimeoutError を補 足しているようには見えませんでした。私はなにか勘違いしているのでしょう か… /usr/local/lib/ruby/1.6/resolv.rb /usr/local/lib/ruby/1.6/ping.rb /usr/local/lib/ruby/1.6/net/telnet.rb /usr/local/lib/ruby/1.6/net/protocol.rb なお、net/protocol.rb では、読み出し関連でも、raise TimeoutError と TimeoutError をそのままあげている部分もあるように見えます。(1.6.8/CVS HEAD) ついでに、書かせていただくと、添付ライブラリのリファレンスマニュアルに、 TimeoutError(またはそのサブクラス)があがることが書いてあると、(私の ように)さらに timeout で囲ってしまう人が減るかもしれません。 勝手申しますが、ご検討いただければ幸いです。 -- 荻野 充 (おぎの みつる) ... 「萩(はぎ)」にあらず Verama Systems Key fingerprint = 7F26 5414 1805 F31B 1617 10B7 C117 07AE 1691 9BD1