How to get the reference alive to the older one, when there is a second exception in Ruby?

begin
  raise "explosion"
rescue
  p $!
  raise "Are you mad"
  p $!
end

# #<RuntimeError: explosion>
# RuntimeError: Are you mad
#    from (irb):5:in `rescue in irb_binding'
#    from (irb):1
#    from /usr/bin/irb:12:in `<main>'

$! always holds only the current exception object reference.

But is there any way to get a reference to the original exception object (here it is “explosion”), after another exception has been raised? <~~~ Here is my question.

Myself tried and reached to the answer,hope now it is more clearer to all who was in Smokey situation with my queries.

  • Rails format validation — alphanumeric, but not purely numeric
  • In ruby on rails 3 is a database only accessible from a user_controller?
  • Ruby Gem randomly returns Encoding Error
  • What's the point of freezing your Rails version/gems?
  • mysql gem vs mysql2 gem and 'each_hash' method
  • Error Installing alpr for ios
  • How to retrieve the current method name so to output it to the logger file?
  • Why does my `require` statement cause a LoadError?
  • 2 Solutions collect form web for “How to get the reference alive to the older one, when there is a second exception in Ruby?”

    Are you saying you want to have reference to the original exception when you rescue the second exception? If so, then you need to capture the original exception in a variable during the rescue. This is done by doing:

    rescue StandardError => e
    

    where StandardError can be any type of exception or omitted (in which case StandardError is the default).

    For example, the code:

    begin
        raise "original exception"
    rescue StandardError => e
        puts "Original Exception:"
        puts $!
        puts e
        begin
            raise "second exception"
        rescue
            puts "Second Exception:"
            puts $!
            puts e      
        end
    end
    

    Gives the output:

    Original Exception:
    original exception
    original exception
    Second Exception:
    second exception
    original exception
    

    As you can see e has stored the original exception for use after the second exception.

    class MyError < StandardError
    attr_reader :original
    def initialize(msg, original=$!)
    super(msg)
    @original = original;
    end
    end
    begin
        begin
        raise "explosion"
        rescue => error
        raise MyError, "Are you mad"
        end
    rescue => error
    puts "Current failure: #{error.inspect}"
    puts "Original failure: #{error.original.inspect}"
    end
    

    OUTPUT

    Current failure: #<MyError: Are you mad>
    Original failure: #<RuntimeError: explosion>
    => nil
    
    Ruby is the best programming language in the world - Ruby on Rails.