модуль ActiveSupport::Rescuable::ClassMethods
Открытые методы экземпляров
# File activesupport/lib/active_support/rescuable.rb, line 53
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_with_handler.
rescue_from получает ряд классов исключений или имен классов, а также обработчик исключений, указанный в конце :with опцией, содержащей имя метода или объект Proc. В качестве обработчика также может быть передан блок.
Обработчики, принимающие один аргумент, будут вызываться с исключением, чтобы его можно было проверить при работе с ним.
Обработчики наследуются. Они ищутся справа налево, снизу вверх и по иерархии. Вызывается обработчик первого класса, для которого exception.is_a?(klass) верно, если такой существует.
class ApplicationController < ActionController::Base
rescue_from User::NotAuthorized, with: :deny_access
rescue_from ActiveRecord::RecordInvalid, with: :show_record_errors
rescue_from "MyApp::BaseError" do |exception|
redirect_to root_url, alert: exception.message
end
private
def deny_access
head :forbidden
end
def show_record_errors(exception)
redirect_back_or_to root_url, alert: exception.record.errors.full_messages.to_sentence
end
end
Исключения, возникшие внутри обработчиков исключений, не распространяются вверх.
# File activesupport/lib/active_support/rescuable.rb, line 90
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 Сопоставляет исключение с обработчиком на основе класса исключения.
Если обработчик не соответствует исключению, проверяется обработчик, соответствующий (необязательному) exception.cause. Если обработчик не соответствует исключению или его причине, возвращается nil, так что вы можете обработать необработанные исключения. Убедитесь, что вы повторно поднимаете необработанные исключения, если это ожидается.
begin # ... rescue => exception rescue_with_handler(exception) || raise end
Возвращает исключение, если оно было обработано, и nil в противном случае.
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.