Module: RescueFrom::Rescuable

Defined in:
lib/rescue_from/rescuable.rb,
sig/lib/rescue_from/rescuable.rbs

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(base) ⇒ Object



5
6
7
8
9
10
11
12
# File 'lib/rescue_from/rescuable.rb', line 5

def self.extended base
  overrider = Module.new do
    extend Overrider
  end

  base.const_set :RescueFrom_Overrider, overrider
  base.prepend overrider
end

Instance Method Details

#inherited(subclass) ⇒ Object



14
15
16
17
18
# File 'lib/rescue_from/rescuable.rb', line 14

def inherited subclass
  super

  subclass.extend Rescuable
end

#method_added(name) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/rescue_from/rescuable.rb', line 40

def method_added name
  super

  return unless should_rescue_in? name

  overrider = const_get :RescueFrom_Overrider

  return if overrider.method_defined? name

  method_without_rescue = instance_method name
  name_without_rescue = :"#{name}_without_rescue"

  overrider.define_method name_without_rescue do |*args, **kwargs, &block|
    method_without_rescue.bind_call(self, *args, **kwargs, &block)
  end

  # rubocop:disable Lint/RescueException
  overrider.define_method name do |*args, **kwargs, &block|
    super(*args, **kwargs, &block)
  rescue Exception => e
    self.class
      .ancestors
      .lazy
      .filter_map { |mod| mod.const_get :RescueFrom_Overrider if mod.const_defined? :RescueFrom_Overrider }
      .filter_map { |ancestor_overrider| ancestor_overrider.handler_for e }
      .first
      .otherwise { raise e }
      .therefore { |handler| instance_exec(e, name, &handler) }
  end
  # rubocop:enable Lint/RescueException

  if private_method_defined? name
    overrider.class_exec do
      private name, name_without_rescue
    end
  elsif protected_method_defined? name
    overrider.class_exec do
      protected name, name_without_rescue
    end
  end
end

#relabel(*patterns, to:) { ... } ⇒ void

This method returns an undefined value.

Parameters:

  • patterns (Array::_Pattern[Exception])
  • to: (Exception)

Yields:

Yield Returns:

  • (void)


30
31
32
33
34
# File 'lib/rescue_from/rescuable.rb', line 30

def relabel *patterns, to:, &message_generator
  rescue_from(*patterns) do |e|
    raise to, instance_exec(e, &message_generator)
  end
end

#rescue_from(*patterns) { ... } ⇒ void

This method returns an undefined value.

Parameters:

  • patterns (Array::_Pattern[Exception])

Yields:

Yield Returns:

  • (void)

Raises:

  • (ArgumentError)


20
21
22
23
24
25
26
27
28
# File 'lib/rescue_from/rescuable.rb', line 20

def rescue_from *patterns, &handler
  raise ArgumentError, 'always provide a handler when calling rescue_from' unless block_given?

  overrider = const_get :RescueFrom_Overrider

  patterns.each do |pattern|
    overrider.handlers[pattern] = handler
  end
end

#should_rescue_in?(_method_name) ⇒ Boolean

Parameters:

  • method_name (Symbol)

Returns:

  • (Boolean)


36
37
38
# File 'lib/rescue_from/rescuable.rb', line 36

def should_rescue_in? _method_name
  true
end