[フレーム]
Last Updated: February 25, 2016
·
2.51K
· jgorset

Reraising an exception as another in Ruby

It's a good idea to reraise exceptions from third-party libraries as your own so you're not leaking implementation details all over your codebase. For example, I would rather deal with my own Facebook::Page::Inaccessible exception than FbGraph::NotFound outside of my Facebook adapter.

If your adapter has lots of places that could leak exceptions, however, reraising them everywhere gets old really fast. We can leverage the new prepend method in Ruby 2.0 to make things really easy and really pretty:

class Adapter
 extend Reraise

 reraise FbGraph::NotFound, as: Facebook::Page::Inaccessible, in: "query"

 def query
 raise FbGraph::NotFound, "This will be reraised as Facebook::Page::Inaccessible"
 end
end

Adapter.new.query # => Facebook::Page::Inaccessible: This will be reraised as Facebook::Page::Inaccessible
module Reraise

 # Rescue a given exception and raise another.
 #
 # old_exception - The Exception to rescue.
 # options - A Hash of options:
 # :as - The Exception class to raise.
 # :in - A String or Array describing affected methods.
 def reraise old_exception, options
 new_exception = options.fetch :as
 methods = options.fetch :in

 methods = [methods] unless methods.respond_to? :each

 proxy = Module.new do
 methods.each do |method|
 define_method method do |*args|
 begin
 super *args
 rescue old_exception => exception
 raise new_exception, exception
 end
 end
 end
 end

 class_eval do
 prepend proxy
 end
 end
end

1 Response
Add your response

I released this as a gem if you're into that kind of thing.

over 1 year ago ·

AltStyle によって変換されたページ (->オリジナル) /