Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #9449: action_controller_rescue_from.2.diff

File action_controller_rescue_from.2.diff, 5.7 kB (added by norbert, 1 year ago)

It's called rescue_from now

  • actionpack/test/controller/rescue_test.rb

    old new  
    33uses_mocha 'rescue' do 
    44 
    55class RescueController < ActionController::Base 
     6  class NotAuthorized < StandardError 
     7  end 
     8 
     9  class RecordInvalid < StandardError 
     10  end 
     11 
     12  rescue_from NotAuthorized, :with => :deny_access 
     13  rescue_from RecordInvalid, :with => :show_errors 
     14 
    615  def raises 
    716    render :text => 'already rendered' 
    817    raise "don't panic!" 
     
    1726  end 
    1827   
    1928  def missing_template; end 
     29 
     30  def not_authorized 
     31    raise NotAuthorized 
     32  end 
     33 
     34  def record_invalid 
     35    raise RecordInvalid 
     36  end 
     37 
     38  protected 
     39    def deny_access 
     40      head :forbidden 
     41    end 
     42 
     43    def show_errors(exception) 
     44      head :unprocessable_entity 
     45    end 
    2046end 
    2147 
    22  
    2348class RescueTest < Test::Unit::TestCase 
    2449  FIXTURE_PUBLIC = "#{File.dirname(__FILE__)}/../fixtures".freeze 
    2550 
     
    3863    end 
    3964  end 
    4065 
    41  
    4266  def test_rescue_action_locally_if_all_requests_local 
    4367    @controller.expects(:local_request?).never 
    4468    @controller.expects(:rescue_action_locally).with(@exception) 
     
    6993    end 
    7094  end 
    7195 
    72  
    7396  def test_rescue_action_in_public_with_error_file 
    7497    with_rails_root FIXTURE_PUBLIC do 
    7598      with_all_requests_local false do 
     
    93116    assert_equal ' ', @response.body 
    94117  end 
    95118 
    96  
    97119  def test_rescue_unknown_action_in_public_with_error_file 
    98120    with_rails_root FIXTURE_PUBLIC do 
    99121      with_all_requests_local false do 
     
    117139    assert_equal ' ', @response.body 
    118140  end 
    119141 
    120  
    121142  def test_rescue_missing_template_in_public 
    122143    with_rails_root FIXTURE_PUBLIC do 
    123144      with_all_requests_local true do 
     
    129150    assert @response.body.include?('missing_template'), "Response should include the template name." 
    130151  end 
    131152 
    132  
    133153  def test_rescue_action_locally 
    134154    get :raises 
    135155    assert_response :internal_server_error 
     
    138158    assert @response.body.include?("don't panic"), "Response should include exception message." 
    139159  end 
    140160 
    141  
    142161  def test_local_request_when_remote_addr_is_localhost 
    143162    @controller.expects(:request).returns(@request).at_least_once 
    144163    with_remote_addr '127.0.0.1' do 
     
    153172    end 
    154173  end 
    155174 
    156  
    157175  def test_rescue_responses 
    158176    responses = ActionController::Base.rescue_responses 
    159177 
     
    182200    assert_equal 'template_error',    templates[ActionView::TemplateError.name] 
    183201  end 
    184202 
    185  
    186203  def test_clean_backtrace 
    187204    with_rails_root nil do 
    188205      # No action if RAILS_ROOT isn't set. 
     
    217234    assert_equal "GET, HEAD, PUT", @response.headers['Allow'] 
    218235  end 
    219236 
     237  def test_rescue_from_not_authorized 
     238    @controller.expects(:rescue_action).never 
     239    get :not_authorized 
     240    assert_response :forbidden 
     241  end 
     242 
     243  def test_rescue_from_record_invalid 
     244    @controller.expects(:rescue_action).never 
     245    @controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) } 
     246    get :record_invalid 
     247  end 
     248 
    220249  protected 
    221250    def with_all_requests_local(local = true) 
    222251      old_local, ActionController::Base.consider_all_requests_local = 
  • actionpack/lib/action_controller/rescue.rb

    old new  
    5050      def process_with_exception(request, response, exception) 
    5151        new.process(request, response, :rescue_action, exception) 
    5252      end 
     53 
     54      # Rescue exceptions raised in controller actions by passing at least one exception class and a :with option that contains the name of the method to be called to respond to the exception. 
     55      # Handler methods that take one argument will be called with the exception, so that the exception can be inspected when dealing with it. 
     56      # 
     57      # class ApplicationController < ActionController::Base 
     58      #   rescue_from User::NotAuthorized, :with => :deny_access # self defined exception 
     59      #   rescue_from ActiveRecord::RecordInvalid, :with => :show_errors 
     60      # 
     61      #   protected 
     62      #     def deny_access 
     63      #       ... 
     64      #     end 
     65      # 
     66      #     def show_errors(exception) 
     67      #       exception.record.new_record? ? ... 
     68      #     end 
     69      # end 
     70      def rescue_from(*klasses) 
     71        options = klasses.extract_options! 
     72        unless handler = options[:with] 
     73          raise ArgumentError, "Need a handler. Supply an options hash that has a :with key as the last argument." 
     74        end 
     75 
     76        klasses.each do |klass| 
     77          write_inheritable_hash(:rescued_exceptions, klass => handler) 
     78        end 
     79      end 
     80 
     81      def exception_handler_for(klass) #:nodoc: 
     82        (read_inheritable_attribute(:rescued_exceptions) || {})[klass] 
     83      end 
    5384    end 
    5485 
    5586    protected 
     
    86117        end 
    87118      end 
    88119 
    89  
    90120      # Overwrite to implement public exception handling (for requests answering false to <tt>local_request?</tt>).  By 
    91121      # default will call render_optional_error_file.  Override this method to provide more user friendly error messages.s 
    92122      def rescue_action_in_public(exception) #:doc: 
     
    132162      def perform_action_with_rescue #:nodoc: 
    133163        perform_action_without_rescue 
    134164      rescue Exception => exception  # errors from action performed 
    135         rescue_action(exception) 
     165        if handler = self.class.exception_handler_for(exception.class) 
     166          args = (handler = method(handler)).arity != 0 ? [exception] : [] 
     167          handler.call(*args) 
     168        else 
     169          rescue_action(exception) 
     170        end 
    136171      end 
    137172 
    138173      def rescues_path(template_name)