Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: Prepend info to exception messages without touching stacktrace

Tags:

exception

ruby

I need to prepend debugging info to all exceptions that occur within a block, but I don't want to mess up the backtrace.$! doesn't seem to be allowing this in 1.9.3; raise is replacing the backtrace regardless of what I try.

Ideas?

Here's what I was using originally:

def self.load(filename, virtual_path = nil)
  t = Template.new(filename, virtual_path)
  t.is_page? ? Page.new(t) : t
rescue
  raise $!, "Error loading template '#{filename}'#{virtual_path ? " under virtual path '" + virtual_path  + "'" : ""}: #{$!}"
end

The best I've found so far is this:

def self.load(filename, virtual_path = nil)
  t = Template.new(filename, virtual_path)
  t.is_page? ? Page.new(t) : t
rescue => e
    raise e, "Error loading template '#{filename}'#{virtual_path ? " under virtual path '" + virtual_path  + "'" : ""}: #{e.message} #{e.backtrace}"
end

This dumps the original stack trace into the message, but still doesn't preserve the old stack trace as the stack trace

like image 679
Lilith River Avatar asked Jul 02 '26 02:07

Lilith River


1 Answers

If you look at the Kernel#raise method, it can take three parameters:

raise(exception [, string [, array]])

If you want to keep the backtrace, you should specify the array parameter, which is the callback information.

Example:

Say you originally had:

def some_method()
    raise('original message')
end

some_method
#=> scratch.rb:10:in `some_method': original message (RuntimeError)
#   from scratch.rb:16:in `<main>'

You can use the third parameter of the exception to raise a new exception with updated message and the same backtrace:

def some_method()
    begin
        raise('error message')
    rescue
        raise $!, 'new message', $!.backtrace
    end
end

some_method
#=> scratch.rb:10:in `some_method': new message (RuntimeError)
#       from scratch.rb:16:in `<main>'

As you can see, the new exception is the same as the original exception, except with the updated message.

like image 190
Justin Ko Avatar answered Jul 04 '26 21:07

Justin Ko