1

Redisライブラリからレイズされたものをレスキューする必要がありTimeout::Errorますが、問題が発生しており、特定のクラスが機能していないようです。

begin
  Redis.new( { :host => "127.0.0.X" } )
rescue Timeout::Error => ex
end

=> Timeout::Error: Timeout::Error from /Users/me/.rvm/gems/ree-1.8.7-2011.03@gowalla/gems/redis-2.2.0/lib/redis/connection/hiredis.rb:23:in `connect'

救助しようとしてExceptionもうまくいかない

begin
  Redis.new( { :host => "127.0.0.X" } )
rescue Exception => ex
end

=> Timeout::Error: Timeout::Error from /Users/me/.rvm/gems/ree-1.8.7-2011.03@gowalla/gems/redis-2.2.0/lib/redis/connection/hiredis.rb:23:in `connect'

手動で例外を発生させようとすると、それをレスキューできますが、Redis Gem(2.2.0)内から呼び出されたときになぜレスキューできないのかわかりません。

begin
  raise Timeout::Error
rescue Timeout::Error => ex
  puts ex 
end

Timeout::Error
=> nil 

この例外を救済する方法の手がかりはありますか?

4

1 に答える 1

5

このコードをirbで実行しましたよね?取得している例外は、実際にはによって発生しているわけではありませんRedis.new。これは、inspect入力した式の値を表示するためにirbが呼び出すメソッドによって発生します。

スタックトレースを見てください(パスを短くして読みやすくしました):

ruby-1.8.7-p330 :009 >   Redis.new(:host => "google.com")
Timeout::Error: time's up!
    from /.../SystemTimer-1.2.3/lib/system_timer/concurrent_timer_pool.rb:63:in `trigger_next_expired_timer_at'
    from /.../SystemTimer-1.2.3/lib/system_timer/concurrent_timer_pool.rb:68:in `trigger_next_expired_timer'
    from /.../SystemTimer-1.2.3/lib/system_timer.rb:85:in `install_ruby_sigalrm_handler'
    from /..../lib/ruby/1.8/monitor.rb:242:in `synchronize'
    from /.../SystemTimer-1.2.3/lib/system_timer.rb:83:in `install_ruby_sigalrm_handler'
    from /.../redis-2.2.2/lib/redis/connection/ruby.rb:26:in `call'
    from /.../redis-2.2.2/lib/redis/connection/ruby.rb:26:in `initialize'
    from /.../redis-2.2.2/lib/redis/connection/ruby.rb:26:in `new'
    from /.../redis-2.2.2/lib/redis/connection/ruby.rb:26:in `connect'
    from /.../SystemTimer-1.2.3/lib/system_timer.rb:60:in `timeout_after'
    from /.../redis-2.2.2/lib/redis/connection/ruby.rb:115:in `with_timeout'
    from /.../redis-2.2.2/lib/redis/connection/ruby.rb:25:in `connect'
    from /.../redis-2.2.2/lib/redis/client.rb:227:in `establish_connection'
    from /.../redis-2.2.2/lib/redis/client.rb:23:in `connect'
    from /.../redis-2.2.2/lib/redis/client.rb:247:in `ensure_connected'
    from /.../redis-2.2.2/lib/redis/client.rb:137:in `process'
... 2 levels...
    from /.../redis-2.2.2/lib/redis/client.rb:46:in `call'
    from /.../redis-2.2.2/lib/redis.rb:90:in `info'
    from /..../lib/ruby/1.8/monitor.rb:242:in `synchronize'
    from /.../redis-2.2.2/lib/redis.rb:89:in `info'
    from /.../redis-2.2.2/lib/redis.rb:1075:in `inspect'
    from /..../lib/ruby/1.8/monitor.rb:242:in `synchronize'
    from /.../redis-2.2.2/lib/redis.rb:1074:in `inspect'
    from /..../lib/ruby/1.8/irb.rb:310:in `output_value'
    from /..../lib/ruby/1.8/irb.rb:159:in `eval_input'
    from /..../lib/ruby/1.8/irb.rb:271:in `signal_status'
    from /..../lib/ruby/1.8/irb.rb:155:in `eval_input'
    from /..../lib/ruby/1.8/irb.rb:154:in `eval_input'
    from /..../lib/ruby/1.8/irb.rb:71:in `start'
    from /..../lib/ruby/1.8/irb.rb:70:in `catch'
    from /..../lib/ruby/1.8/irb.rb:70:in `start'
    from /..../bin/irb:17

上記のように、例外はでinspectはなく、の内部で発生しますRedis.newinspectRedisオブジェクトを呼び出すと、その状態を単に出力するのではなく、実際に多くのことを実行します。この場合、inspectサーバーへの接続を試み、タイムアウトすると例外をスローします。これは私には非常に悪い設計のように思われるので、Redisgemのメンテナにバグレポートを提出する必要があるかもしれません。

これにより、IRBでいくつかの興味深い動作が発生します。

  • 上記のように入力Redis.new(:host => "google.com")すると例外が発生します
  • 入力Redis.new(:host => "google.com"); 'hello'すると' => "hello"'になります

この例外をキャッチしたい場合はensure_connected、begin / rescue/endブロック内で呼び出してみてください。

于 2011-08-12T18:40:26.927 に答える