Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DRY way of re-raising same set of exceptions in multiple places

short:

Is there a way in Ruby to DRY-ify this:

def entry_point_one
  begin
    do_something
  rescue MySyntaxErrorOne, MySyntaxErrorTwo, MySyntaxErrorEtc => syn_err
    raise syn_err.exception(syn_err.message)
  end
end

def entry_point_two
  begin
    do_something_else
  rescue MySyntaxErrorOne, MySyntaxErrorTwo, MySyntaxErrorEtc => syn_err
    raise syn_err.exception(syn_err.message)
  end
end

longer:

I'm building an interpreter. This interpreter can be called using different entry points. If I feed this interpreter a 'dirty' string, I expect it to raise an error. However, it would be nice if I don't get spammed by the by the entire back trace of every method called directly or indirectly by do_something, especially since the interpreter makes use of recursion.

As you can see in the above snippet, I already know a way to re raise an error and thereby removing the back trace. What I would like do is remove the duplication in the above example. The closest I have come thus far is this:

def entry_point_one
  re_raise_known_exceptions {do_something}
end

def entry_point_two
  re_raise_known_exceptions {do_something_else}
end

def re_raise_known_exceptions
  yield
rescue MySyntaxErrorOne, MySyntaxErrorTwo, MySyntaxErrorEtc => syn_err
    raise syn_err.exception(syn_err.message)
end

But that makes the method re-raise-known-exceptions show up in the back trace.

edit: I guess what I want would be something like a C pre-processing macro

like image 652
Patrick Huizinga Avatar asked Dec 06 '25 04:12

Patrick Huizinga


2 Answers

You can just use the splat on an array.

Straight from IRB:

COMMON_ERRORS = [ArgumentError, RuntimeError] # add your own 

def f
  yield
rescue *COMMON_ERRORS => err
  puts "Got an error of type #{err.class}"
end


f{ raise ArgumentError.new }
Got an error of type ArgumentError

f{ raise 'abc' }
Got an error of type RuntimeError
like image 167
Orion Edwards Avatar answered Dec 09 '25 15:12

Orion Edwards


while thinking about it a bit more, I came up with this:

interpreter_block {do_something}

def interpreter_block
  yield
rescue ExceptionOne, ExceptionTwo, ExceptionEtc => exc
  raise exc.exception(exc.message)
end

Although it's still not quiet what I would like to have, at least now the extra entry in the back trace has become somewhat better looking.

like image 45
Patrick Huizinga Avatar answered Dec 09 '25 17:12

Patrick Huizinga



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!