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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With