Preserving backtrace during exceptions wrapping in Ruby
In this example raising a CustomError
hides the original error backtrace.
CustomError = Class.new(StandardError)
def raise_error
raise StandardError, "Original error" # line 4
end
def call_the_error_raiser
raise_error # line 8
rescue => e
raise CustomError, "Error message"
end
begin
call_the_error_raiser # line 14
rescue StandardError => e
puts e.inspect
puts e.backtrace.join("\n")
end
Output (the cause of the original error is lost):
#<CustomError: Error message>
preserve_error_backtrace.rb:10:in `rescue in call_the_error_raiser'
preserve_error_backtrace.rb:7:in `call_the_error_raiser'
preserve_error_backtrace.rb:14:in `<main>'
You can still access the "Original error" backtrace via Exception#cause
, but it may be better to preserve the original while raising the custom error, instead of generating a new non-helpful backtrace:
raise CustomError, "Error message", e.backtrace
Output (the cause of the original error is on the first line):
#<CustomError: Error message>
preserve_error_backtrace.rb:4:in `raise_error' ← The cause of the error
preserve_error_backtrace.rb:8:in `call_the_error_raiser'
preserve_error_backtrace.rb:14:in `<main>'
References:
- Nested errors in Ruby with Exception#cause at Honeybadger blog
Exception#cause
docs
Somewhat related: