方法
实例公共方法
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