Only run a specific code block after rescue in Ruby

Viewed 372

I know that ensure will run regardless of whether an exception was thrown or not, but is there a way to only run a code block after rescue has been called? I'm asking because what if there were multiple rescue blocks that ended in the program exiting (or doing the same thing), is there a more efficient way of calling abort or exit at the end of each rescue block?

3 Answers

How about reraising the exception under rescue using another begin/rescue/ensure/end block?

def foo(error_class)
  raise error_class, "raising an error..."
rescue Exception => e
  begin
    raise e
  rescue ArgumentError
    puts 'check your arguments please'
  rescue LocalJumpError
    puts "something's wrong with your block"
  ensure
    puts 'done handling the exception!'
  end
end

The ensure in the inner code block will only hit after an exception.

No, there is no such construct in Ruby. Exception handling offers you three things:

  • rescue, which allows you to execute code if a specific (set of) exception(s) is raised.
  • ensure, which allows you to execute code regardless of whether an exception was raised.
  • else, which allows you to execute code if no exception was raised.

There is no construct that allows you to execute code if any exception was raised. What you are looking for is essentially the opposite of else which doesn't exist.

There are, of course, ways to implement what you want, but all of those ways will add at least as much code and complexity as your existing solution.

There's no such thing.

But if your return value is the same whenever an exception occurs, you could use a begin/end block and then insert the return statement after such block.

class Test
  def self.testing
    begin
      puts 'A'
      return true
    rescue StandardError
      puts 'B'
    end
    puts 'C'
    false
  end
end

The code above would print 'A' and return true only.

class Test
  def self.testing
    begin
      puts 'A'
      puts "#{2 / 0}"
      return true
    rescue StandardError
      puts 'B'
    end
    puts 'C'
    false
  end
end

This would print 'A', 'B', 'C' and return false.

Related