2011-08-12 48 views
1

我需要挽救從Redis庫中引發的Timeout::Error,但是我遇到了一個問題,救出那個特定的類似乎不起作用。救援超時::錯誤來自Redis Gem(Ruby)

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

=> Timeout::Error: Timeout::Error from /Users/me/.rvm/gems/[email protected]/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/[email protected]/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 

任何線索如何拯救此異常?

回答

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.new。當您在Redis對象上調用inspect時,不僅僅是打印出它的狀態,它實際上還做了很多事情。在這種情況下,inspect嘗試連接到服務器,並在超時時引發異常。這對我來說似乎是一個非常糟糕的設計,也許我們應該向Redis Gem的維護者提交一個錯誤報告。

這導致了一些有趣的行爲在IRB:如果你想趕上這個

  • 鍵入Redis.new(:host => "google.com")導致異常如上圖所示
  • 鍵入Redis.new(:host => "google.com"); 'hello'會導致「=> "hello"

例外,請嘗試在您的開始/救援/結束區塊內呼叫ensure_connected

+0

就我而言(參見上面的問題,如果我的編輯被批准),這個答案幫助我弄清楚IRB的「昆蟲」是問題的根源。 謝謝Devid! –