方法
实例公共方法
rescue_from(*klasses, with: nil, &block) 链接
使用处理程序注册异常类,由 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
异常处理程序中引发的异常不会向上传播。
来源:显示 | 在 GitHub 上
# 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(exception, object: self, visited_exceptions: []) 链接
根据异常类将异常与处理程序匹配。
如果没有任何处理程序与异常匹配,请检查是否有处理程序与(可选)exception.cause
匹配。如果没有任何处理程序与异常或其原因匹配,则返回 nil
,以便您可以处理未处理的异常。请务必重新引发未处理的异常(如果这是您的预期)。
begin
# ...
rescue => exception
rescue_with_handler(exception) || raise
end
如果已处理异常,则返回该异常;如果未处理,则返回 nil
。
来源:显示 | 在 GitHub 上
# 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