It is always a good practice to rescue exceptions in Ruby, but be aware that, keep best the practices all times even when you are doing your rescue magic.Rescue someone unwilling to look after himself, and he will cling to you like a dangerous illness. --Mason Cooley
Let us take a look at the following code:
begin HTTParty.get(@url, :timeout => 5) rescue "Time out!" end
It is supposed to return the "Time Out!" string, but instead it just throws out a Ruby error. Obviously my magic couldn't rescue me for some reason which is unknown to me. I muddled around for a while, it just would not work for me.
Did a bit digging on the net and I found a few articles which pulled me out of the mud. One is "Ruby Exceptions" from Ruby Learning, the other is "Ruby Timeout::Error" from Marcin Ciunelis. So I updated my code to the following, and it worked:
begin HTTParty.get(@url, :timeout => 5) rescue Exception=>exception "#{exception.inspect}" end
So, in one word: Rescue will only rescue StandardError by default, and Timeout error is not a StandardError, depending on the Ruby version you are using. The following is an overview of the Ruby Exception structure:
Digging deeper, I found something even more interesting. If anyone of you are using different Rubies in different projects, you should be aware of this:
#rvm 1.8.7 #irb #require 'timeout' >> Timeout::Error.ancestors => [Timeout::Error, Interrupt, SignalException, Exception, Object, Kernel]
#rvm 1.9.3 #irb #require 'timeout' >> Timeout::Error.ancestors => [Timeout::Error, RuntimeError, StandardError, Exception, Object, Kernel, BasicObject]
You see the difference? Jruby 1.6 is supposed to be the equivalent of MRI Ruby 1.9, but the Timeout Exception structure is the same with 1.8.#rvm jruby-1.6.5 #irb #require 'timeout' >> Timeout::Error.ancestors => [Timeout::Error, Interrupt, SignalException, Exception, Object, Kernel]
It got me. Did it get you?
Hope this helps.
Cheers,
Felix
No comments:
Post a Comment