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