É uma boa ideia relançar exceções de bibliotecas de terceiros como se fossem suas, para não vazar detalhes de implementação em toda a sua base de código. Por exemplo, prefiro lidar com minha própria Facebook::Page::Inaccessible
exceção do que FbGraph::NotFound
fora do meu adaptador do Facebook.
Se o seu adaptador tem muitos lugares que podem vazar exceções, no entanto, reaumentá-los em todos os lugares envelhece muito rápido. Podemos aproveitar o novo prepend
método em Ruby 2.0 para tornar as coisas realmente fáceis e bonitas:
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