10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
# File 'lib/retry_unsafe_method/retry_unsafe_method.rb', line 10
def retry_unsafe_method(method_name, retry_count, *exceptions, &block)
unless method_defined?(method_name) || private_method_defined?(method_name)
raise StandardError.new("method #{method_name} is not defined")
end
if block_given?
raise StandardError.new('you must not pass exceptions and block simultaneously') if exceptions.size > 0
check_proc = block
else
raise StandardError.new('you must pass exceptions or block') if exceptions.size == 0
check_proc = Proc.new { |e| exceptions.map(&:to_s).include?(e.class.to_s) }
end
safe_method_name = :"#{method_name}_safe_with_retry"
unsafe_method_name = :"#{method_name}_unsafe_without_retry"
define_method(safe_method_name) do |*args, &block|
begin
__send__(unsafe_method_name, *args, &block)
rescue StandardError => e
ivar = :"@current_retry_#{method_name}"
if check_proc.call(e)
instance_variable_set(ivar, 0) unless instance_variable_defined?(ivar)
if instance_variable_get(ivar) < retry_count
instance_variable_set(ivar, instance_variable_get(ivar) + 1)
retry
else
remove_instance_variable(ivar)
raise e
end
else
remove_instance_variable(ivar) if instance_variable_defined?(ivar)
raise e
end
end
end
if private_method_defined?(method_name)
private safe_method_name
elsif protected_method_defined?(method_name)
protected safe_method_name
else
public safe_method_name
end
alias_method unsafe_method_name, method_name
alias_method method_name, safe_method_name
end
|