class A
def a_method
#..
end
end
class B < A
def method_1
# ...
a_method
end
def method_2
# ...
a_method
end
# ...
def method_n
# ...
a_method
end
end
The a_method
ocassionally throws an AException.
I want to rescue from that exception, like:
class B < A
def method_1
# ...
a_method
rescue AException => e
p e.message
end
# ...
end
I want to rescue the same way in each methods inside class B (method_1
, method_2
, ..., method_n
). I'm stuck on figuring out a nice and clean solution, that would not require to duplicate the rescue code block. Can you help me with that?
How about to use a block:
class B < A
def method_1
# some code here which do not raised an exception
with_rescue do
# method which raised exception
a_method
end
end
def method_2
with_rescue do
# ...
a_method
end
end
private
def with_rescue
yield
rescue => e
...
end
end
If you want to always rescue the exception, you could just override a_method
in B
:
class B < A
def a_method
super
rescue AException => e
p e.message
end
# ...
end
In addition you might want to return a value (like nil
or false
) to indicate the failure.
Like this, perhaps?
class B < A
def method_1
# ...
safe_a_method
end
private
def safe_a_method
a_method
rescue AException => e
...
end
end
You can wrap your methods using a Module like this. The benefit is that unlike the other solutions you can call your methods with their regular names and the methods themselves don't have to be changed. Just extend the class with the ErrorHandler method en at the end enumerate the methods to wrap them with your errorhandling logic.
module ErrorHandler
def wrap(method)
old = "_#{method}".to_sym
alias_method old, method
define_method method do |*args|
begin
send(old, *args)
rescue => e
puts "ERROR FROM ERRORHANDLER #{e.message}"
end
end
end
end
class A
extend ErrorHandler
def a_method v
"a_method gives #{v.length}"
end
(self.instance_methods - Object.methods).each {|method| wrap method}
end
class B < A
extend ErrorHandler
def method_1 v
"method_1 gives #{v.length}"
end
(self.instance_methods - Object.methods).each {|method| wrap method}
end
puts A.new.a_method "aa" # a_method gives 2
puts A.new.a_method 1 # ERROR FROM ERRORHANDLER undefined method `length' for 1:Fixnum
puts B.new.method_1 1 # ERROR FROM ERRORHANDLER undefined method `length' for 1:Fixnum
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With