Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby reraising exception w/ additional string argument

Tags:

exception

ruby

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 suggestions on how I can reraise the original exception, but also keep track of all the exceptions that are occurring within doStuff()?

like image 840
Crazy Dan 11 Avatar asked Aug 30 '11 23:08

Crazy Dan 11


2 Answers

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.

  1. doStuff() method doesn't follow Ruby naming conventions. You should use underscore for methods. Please use do_stuff. Also, no need to use () if there are no arguments.
  2. 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.
like image 82
Simone Carletti Avatar answered Oct 20 '22 04:10

Simone Carletti


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
like image 27
Peter Ramm Avatar answered Oct 20 '22 06:10

Peter Ramm