модуль ActiveSupport::Rescuable::ClassMethods
Открытые методы экземпляров
# File activesupport/lib/active_support/rescuable.rb, line 50
def rescue_from(*klasses, with: nil, &block)
unless with
if block_given?
with = block
else
raise ArgumentError, 'Need a handler. Pass the with: keyword argument or provide a block.'
end
end
klasses.each do |klass|
key = if klass.is_a?(Module) && klass.respond_to?(:===)
klass.name
elsif klass.is_a?(String)
klass
else
raise ArgumentError, "#{klass.inspect} must be an Exception class or a String referencing an Exception class"
end
# Put the new handler at the end because the list is read in reverse.
self.rescue_handlers += [[key, with]]
end
end Обрабатывает исключения, поднятые в действиях контроллера.
rescue_from получает ряд классов исключений или их имен, и опцию :with с именем метода или объекта Proc для обработки исключений. В качестве альтернативы можно указать блок.
Обработчики, принимающие один аргумент, будут вызываться с исключением, чтобы его можно было проверить при обработке.
Обработчики наследуются. Они ищутся справа налево, снизу вверх и по иерархии. Обработчик первого класса, для которого exception.is_a?(klass) выполняется, вызывается, если он есть.
class ApplicationController < ActionController::Base
rescue_from User::NotAuthorized, with: :deny_access # self defined exception
rescue_from ActiveRecord::RecordInvalid, with: :show_errors
rescue_from 'MyAppError::Base' do |exception|
render xml: exception, status: 500
end
protected
def deny_access
...
end
def show_errors(exception)
exception.record.new_record? ? ...
end
end Исключения, поднятые внутри обработчиков исключений, не распространяются вверх.
# File activesupport/lib/active_support/rescuable.rb, line 87
def rescue_with_handler(exception, object: self, visited_exceptions: [])
visited_exceptions << exception
if handler = handler_for_rescue(exception, object: object)
handler.call exception
exception
elsif exception
if visited_exceptions.include?(exception.cause)
nil
else
rescue_with_handler(exception.cause, object: object, visited_exceptions: visited_exceptions)
end
end
end Сопоставляет исключение с обработчиком на основе класса исключения.
Если обработчик не соответствует исключению, проверяется обработчик, соответствующий (необязательному) исключению.cause. Если ни исключение, ни его причина не соответствуют обработчику, функция возвращает nil, чтобы вы могли обрабатывать необработанные исключения. Убедитесь, что вы перевыбрасываете необработанные исключения, если это ожидаемое поведение.
begin … rescue => exception rescue_with_handler(exception) || raise end
Возвращает исключение, если оно было обработано, и nil если оно не было обработано.
© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.