Ticket #9449: action_controller_rescue_from.2.diff
| File action_controller_rescue_from.2.diff, 5.7 kB (added by norbert, 1 year ago) |
|---|
-
actionpack/test/controller/rescue_test.rb
old new 3 3 uses_mocha 'rescue' do 4 4 5 5 class 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 6 15 def raises 7 16 render :text => 'already rendered' 8 17 raise "don't panic!" … … 17 26 end 18 27 19 28 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 20 46 end 21 47 22 23 48 class RescueTest < Test::Unit::TestCase 24 49 FIXTURE_PUBLIC = "#{File.dirname(__FILE__)}/../fixtures".freeze 25 50 … … 38 63 end 39 64 end 40 65 41 42 66 def test_rescue_action_locally_if_all_requests_local 43 67 @controller.expects(:local_request?).never 44 68 @controller.expects(:rescue_action_locally).with(@exception) … … 69 93 end 70 94 end 71 95 72 73 96 def test_rescue_action_in_public_with_error_file 74 97 with_rails_root FIXTURE_PUBLIC do 75 98 with_all_requests_local false do … … 93 116 assert_equal ' ', @response.body 94 117 end 95 118 96 97 119 def test_rescue_unknown_action_in_public_with_error_file 98 120 with_rails_root FIXTURE_PUBLIC do 99 121 with_all_requests_local false do … … 117 139 assert_equal ' ', @response.body 118 140 end 119 141 120 121 142 def test_rescue_missing_template_in_public 122 143 with_rails_root FIXTURE_PUBLIC do 123 144 with_all_requests_local true do … … 129 150 assert @response.body.include?('missing_template'), "Response should include the template name." 130 151 end 131 152 132 133 153 def test_rescue_action_locally 134 154 get :raises 135 155 assert_response :internal_server_error … … 138 158 assert @response.body.include?("don't panic"), "Response should include exception message." 139 159 end 140 160 141 142 161 def test_local_request_when_remote_addr_is_localhost 143 162 @controller.expects(:request).returns(@request).at_least_once 144 163 with_remote_addr '127.0.0.1' do … … 153 172 end 154 173 end 155 174 156 157 175 def test_rescue_responses 158 176 responses = ActionController::Base.rescue_responses 159 177 … … 182 200 assert_equal 'template_error', templates[ActionView::TemplateError.name] 183 201 end 184 202 185 186 203 def test_clean_backtrace 187 204 with_rails_root nil do 188 205 # No action if RAILS_ROOT isn't set. … … 217 234 assert_equal "GET, HEAD, PUT", @response.headers['Allow'] 218 235 end 219 236 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 220 249 protected 221 250 def with_all_requests_local(local = true) 222 251 old_local, ActionController::Base.consider_all_requests_local = -
actionpack/lib/action_controller/rescue.rb
old new 50 50 def process_with_exception(request, response, exception) 51 51 new.process(request, response, :rescue_action, exception) 52 52 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 53 84 end 54 85 55 86 protected … … 86 117 end 87 118 end 88 119 89 90 120 # Overwrite to implement public exception handling (for requests answering false to <tt>local_request?</tt>). By 91 121 # default will call render_optional_error_file. Override this method to provide more user friendly error messages.s 92 122 def rescue_action_in_public(exception) #:doc: … … 132 162 def perform_action_with_rescue #:nodoc: 133 163 perform_action_without_rescue 134 164 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 136 171 end 137 172 138 173 def rescues_path(template_name)