From 45904c5a7a552f11714b1e7ad8d27e2eae4e624d Mon Sep 17 00:00:00 2001 From: Serge Balyuk Date: Sun, 30 May 2010 15:58:53 +0300 Subject: [PATCH] fixed dispatcher error handling for exceptions other than RuntimeErrors --- actionpack/lib/action_controller/dispatcher.rb | 10 ++++- .../application_controller.rb | 7 ++++ .../behaviors/some_module.rb | 2 + .../behaviors/with_syntax_error.rb | 3 ++ .../test/controller/dispatcher_rescue_test.rb | 36 ++++++++++++++++++++ 5 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 actionpack/test/controller/controller_fixtures_with_load_error/application_controller.rb create mode 100644 actionpack/test/controller/controller_fixtures_with_load_error/behaviors/some_module.rb create mode 100644 actionpack/test/controller/controller_fixtures_with_load_error/behaviors/with_syntax_error.rb create mode 100644 actionpack/test/controller/dispatcher_rescue_test.rb diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb index 1932944..fb55936 100644 --- a/actionpack/lib/action_controller/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatcher.rb @@ -86,10 +86,16 @@ module ActionController run_callbacks :before_dispatch Routing::Routes.call(@env) rescue Exception => exception - if controller ||= (::ApplicationController rescue Base) + controller ||= begin + ApplicationController + rescue Exception + Base + end + + if controller controller.call_with_exception(@env, exception).to_a else - raise exception + raise end ensure run_callbacks :after_dispatch, :enumerator => :reverse_each diff --git a/actionpack/test/controller/controller_fixtures_with_load_error/application_controller.rb b/actionpack/test/controller/controller_fixtures_with_load_error/application_controller.rb new file mode 100644 index 0000000..2cd984c --- /dev/null +++ b/actionpack/test/controller/controller_fixtures_with_load_error/application_controller.rb @@ -0,0 +1,7 @@ +class ApplicationController < ActionController::Base + + include Behaviors::SomeModule + + include Behaviors::WithSyntaxError + +end diff --git a/actionpack/test/controller/controller_fixtures_with_load_error/behaviors/some_module.rb b/actionpack/test/controller/controller_fixtures_with_load_error/behaviors/some_module.rb new file mode 100644 index 0000000..af612a3 --- /dev/null +++ b/actionpack/test/controller/controller_fixtures_with_load_error/behaviors/some_module.rb @@ -0,0 +1,2 @@ +module Behaviors::SomeModule +end diff --git a/actionpack/test/controller/controller_fixtures_with_load_error/behaviors/with_syntax_error.rb b/actionpack/test/controller/controller_fixtures_with_load_error/behaviors/with_syntax_error.rb new file mode 100644 index 0000000..0fae07c --- /dev/null +++ b/actionpack/test/controller/controller_fixtures_with_load_error/behaviors/with_syntax_error.rb @@ -0,0 +1,3 @@ +module Behaviors::WithSyntaxError +end +end diff --git a/actionpack/test/controller/dispatcher_rescue_test.rb b/actionpack/test/controller/dispatcher_rescue_test.rb new file mode 100644 index 0000000..3f11f6c --- /dev/null +++ b/actionpack/test/controller/dispatcher_rescue_test.rb @@ -0,0 +1,36 @@ +require 'abstract_unit' + +class DispatcherRescueTest < Test::Unit::TestCase + + class SpecificException < RuntimeError; end + + def setup + @load_paths, ActiveSupport::Dependencies.load_paths = ActiveSupport::Dependencies.load_paths, [File.dirname(__FILE__) + '/controller_fixtures_with_load_error/'] + backup_application_controller_class + end + + def teardown + ActiveSupport::Dependencies.load_paths = @load_paths + restore_application_controller_class + end + + def test_application_controller_load_error_does_not_break_dispatcher + ActiveSupport::Dependencies.remove_constant 'ApplicationController' + + assert_raise(SyntaxError) { ::ApplicationController } + ActionController::Routing::RouteSet.any_instance.stubs(:call).raises(SpecificException) + ActionController::Base.expects(:call_with_exception).with(anything, instance_of(SpecificException)).once + ActionController::Dispatcher.new.call({}) + end + + private + + def backup_application_controller_class + @saved_class = Object.const_get(:ApplicationController) if Object.const_defined?(:ApplicationController) + end + + def restore_application_controller_class + Object.const_set(:ApplicationController, @saved_class) if @saved_class + end + +end -- 1.6.3.3