Spec-Zone.ru › Ruby on Rails 5.2

module ActiveSupport::Rescuable::ClassMethods

Методы публичного экземпляра

rescue_from(*klasses, with: nil, &block) Показать исходный код
# File activesupport/lib/active_support/rescuable.rb, line 51
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

  private
    def deny_access
      ...
    end

    def show_errors(exception)
      exception.record.new_record? ? ...
    end
end

Исключения, возникшие внутри обработчиков исключений, не распространяются вверх.

rescue_with_handler(exception, object: self, visited_exceptions: []) Показать исходный код
# File activesupport/lib/active_support/rescuable.rb, line 88
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

Сопоставление исключения с обработчиком на основе класса исключения.

Если ни один обработчик не соответствует исключению, проверяется наличие обработчика, соответствующего (необязательному) причине исключения. Если ни один обработчик не соответствует исключению или его причине, это возвращает nil, чтобы вы могли обработать необработанные исключения. Убедитесь, что вы повторно выбрасываете необработанные исключения, если это ожидаемый результат.

begin
  …
rescue => exception
  rescue_with_handler(exception) || raise
end

Возвращает исключение, если оно было обработано, и nil — если нет.

© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API