Module: ActiveSupport::Rescuable

Extended by:
Concern
Defined in:
lib/active_support/rescuable.rb

Overview

Rescuable module adds support for easier exception handling.

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Methods included from Concern

append_features, extended, included

Instance Method Details

#handler_for_rescue(exception) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/active_support/rescuable.rb', line 85

def handler_for_rescue(exception)
  # We go from right to left because pairs are pushed onto rescue_handlers
  # as rescue_from declarations are found.
  _, rescuer = self.class.rescue_handlers.reverse.detect do |klass_name, handler|
    # The purpose of allowing strings in rescue_from is to support the
    # declaration of handler associations for exception classes whose
    # definition is yet unknown.
    #
    # Since this loop needs the constants it would be inconsistent to
    # assume they should exist at this point. An early raised exception
    # could trigger some other handler and the array could include
    # precisely a string whose corresponding constant has not yet been
    # seen. This is why we are tolerant to unknown constants.
    #
    # Note that this tolerance only matters if the exception was given as
    # a string, otherwise a NameError will be raised by the interpreter
    # itself when rescue_from CONSTANT is executed.
    klass = self.class.const_get(klass_name) rescue nil
    klass ||= klass_name.constantize rescue nil
    exception.is_a?(klass) if klass
  end

  case rescuer
  when Symbol
    method(rescuer)
  when Proc
    if rescuer.arity == 0
      Proc.new { instance_exec(&rescuer) }
    else
      Proc.new { |_exception| instance_exec(_exception, &rescuer) }
    end
  end
end

#rescue_with_handler(exception) ⇒ Object

Tries to rescue the exception by looking up and calling a registered handler.



78
79
80
81
82
83
# File 'lib/active_support/rescuable.rb', line 78

def rescue_with_handler(exception)
  if handler = handler_for_rescue(exception)
    handler.arity != 0 ? handler.call(exception) : handler.call
    true # don't rely on the return value of the handler
  end
end