0

In Ruby/Rails, is there a "catch-all" rescue statement that also allows for more specific rescue possibilities? I tried

begin
  # something
rescue URI::InvalidURIError
  # do something
rescue SocketError
  # do something else
rescue 
  # do yet another thing
end

It turns out that even when there's URI::InvalidURIError or SocketError, it goes into the last rescue (i.e. it executes do yet another thing.) I want it to do something, or do something else, respectively.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
JJ Beck
  • 5,193
  • 7
  • 32
  • 36
  • 1
    First, I doubt that when a `URI::InvalidURIError` or `SocketError` is raised it goes into the last `rescue`—that's just not how Ruby works. Second, you want something that gets everything else, but is specific? Not sure if that even makes semantic sense, as a catch-all is, by definition, non-specific. – Andrew Marshall Nov 24 '12 at 21:53
  • 2
    I think maybe he meant that he needs a solution for more specific rescues because he believes the correct way doesn't work. Perhaps what's really happening is that a different error is being thrown in the block before the errors you expect. You should probably inspect the error that you're actually catching in that last rescue to see what's happening. – numbers1311407 Nov 24 '12 at 21:54
  • @numbers1311407 Thanks for your suggestion. How could I inspect the error I'm catching in the last rescue? – JJ Beck Nov 24 '12 at 23:00
  • `Rails.logger.error(!$)` or change the rescue to `rescue => e`, then `Rails.logger.error(e)`. It'll show up in your log. Or, go ahead and reraise it so it's not caught at all by `raise $!` in the block. – numbers1311407 Nov 24 '12 at 23:01
  • @AndrewMarshall and numbers1311407 You're all correct. I misunderstood something. Thanks all! – JJ Beck Nov 25 '12 at 02:49

1 Answers1

0
require 'uri'
require 'socket'

Errors = [URI::InvalidURIError, SocketError]
a = lambda { |e=nil|
             begin
               raise e unless e.nil? 
             rescue URI::InvalidURIError
               puts "alligator"
             rescue SocketError
               puts "crocodile"
             rescue
               puts "vulture"
             else
               puts "rhino"
             end }

Now try

a.( Errors[ 0 ] )
a.( Errors[ 1 ] )
a.call

It will behave exactly as you need. If your code above doesn't work, then something else is going on in your program than you think.

Boris Stitnicky
  • 12,444
  • 5
  • 57
  • 74