Ruby reraising exception w/ additional string argument
Here is the situation. I want all exceptions in doStuff() to bubble up through the code so that they are handled at a higher level.
I'd also like to record how often any exceptions are happening in doStuff() at a higher level as well, and am currently doing this:
begin
doStuff()
rescue Exception =>
raise e, "specific error to log in a db"
doStuff code throw dozens of exceptions, and I want to capture each of these events to put in the db. There is a doStuff2(), which also can throw identical instructions, and I want to know which function they came from.
Adding the additional string, seems to change the exception itself, and I lose all the nice formatting and trace information that the original exception had.
Any suggestio开发者_开发知识库ns on how I can reraise the original exception, but also keep track of all the exceptions that are occurring within doStuff()?
If you call raise
without passing any argument, Ruby will re-raise the last exception.
begin
doStuff()
rescue => e
log_exception(e)
raise # This will re-raise the last exception.
end
As a side note, I'd like to give you some suggestions about Ruby best practices.
doStuff()
method doesn't follow Ruby naming conventions. You should use underscore for methods. Please usedo_stuff
. Also, no need to use()
if there are no arguments.- Never rescue Exception, instead rescue the most low-level class you need to rescue. In most cases, you might want to rescue all kind of StandardError or RuntimeError. In fact, if you use rescue without passing the error type, Ruby will automatically rescue any subclass of StandardError.
Exception
class is very low level and it will catch syntax errors as well, and several other compiler issues. You might want to let the application crash in this case so that you are not deploying a broken application.
You can save the backtrace and message of the first exception and construct a new exception to raise
begin
rescue Exception => e
new_ex = Exception.new("Error while executing ...:#{e.message}")
new_ex.set_backtrace(e.backtrace)
raise new_ex
end
You can't raise a new Exception and save the previous exception and its stacktrace out of the box. Nested exceptions from Java world are not here out of the box unfortunately. It will be available in Ruby 2.1. It's quite a hot topic. https://bugs.ruby-lang.org/issues/8257
You may still use nesty
gem to have it. What you only need is to include Nesty::NestedError
in your exception classes. More information is here: https://github.com/skorks/nesty/
精彩评论