救援超时:: Redis Gem(Ruby)出错
我需要拯救从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'
如果我尝试手动提升exception,我可以拯救它,但不知道为什么我从Redis Gem(2.2.0)中调用它时无法解救它。
begin raise Timeout::Error rescue Timeout::Error => ex puts ex end Timeout::Error => nil
有什么线索如何解救这个例外?
你用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
如上所示,exception发生在inspect
内部,而不是Redis.new
。 当你在Redis对象上调用inspect
时,它实际上做了很多事情,而不仅仅是打印出它的状态。 在这种情况下, inspect
尝试连接到服务器并在超时时抛出exception。 这对我来说似乎是一个非常糟糕的设计,也许我们应该向Redis gem的维护者提交错误报告。
这导致IRB中一些有趣的行为:
- 键入
Redis.new(:host => "google.com")
导致exception,如上所示 - 输入
Redis.new(:host => "google.com"); 'hello'
Redis.new(:host => "google.com"); 'hello'
导致’=> "hello"
”
如果要捕获此exception,请尝试在begin / rescue / end块内调用ensure_connected
。