diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 26c4703150028fb9e1a162889cbef10069f6b2f2..51e377b084e1ed14a11bc55597bd4129a76668c9 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,5 +1,7 @@ ## Rails 3.2.0 (unreleased) ## +* Allow rescue responses to be configured through a railtie as in `config.action_dispatch.rescue_responses`. Please look at ActiveRecord::Railtie for an example. *José Valim* + * Assets should use the request protocol by default or default to relative if no request is available *Jonathan del Strother* * Log "Filter chain halted as CALLBACKNAME rendered or redirected" every time a before callback halts *José Valim* diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index c850e25507ef98d2d919e3112f2d5aba7776d18f..420cd99ca17ee95d09323437e0a71044d9319ae7 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -12,26 +12,22 @@ class ShowExceptions cattr_accessor :rescue_responses @@rescue_responses = Hash.new(:internal_server_error) - @@rescue_responses.update({ + @@rescue_responses.merge!( 'ActionController::RoutingError' => :not_found, 'AbstractController::ActionNotFound' => :not_found, - 'ActiveRecord::RecordNotFound' => :not_found, - 'ActiveRecord::StaleObjectError' => :conflict, - 'ActiveRecord::RecordInvalid' => :unprocessable_entity, - 'ActiveRecord::RecordNotSaved' => :unprocessable_entity, 'ActionController::MethodNotAllowed' => :method_not_allowed, 'ActionController::NotImplemented' => :not_implemented, 'ActionController::InvalidAuthenticityToken' => :unprocessable_entity - }) + ) cattr_accessor :rescue_templates @@rescue_templates = Hash.new('diagnostics') - @@rescue_templates.update({ + @@rescue_templates.merge!( 'ActionView::MissingTemplate' => 'missing_template', 'ActionController::RoutingError' => 'routing_error', 'AbstractController::ActionNotFound' => 'unknown_action', 'ActionView::Template::Error' => 'template_error' - }) + ) FAILSAFE_RESPONSE = [500, {'Content-Type' => 'text/html'}, ["

500 Internal Server Error

" << diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb index f18ebabf2962376efa5a262d6bea5a51d2783fb2..36a31be0c2ff5227dd461de1df3424bf54ef3984 100644 --- a/actionpack/lib/action_dispatch/railtie.rb +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -9,11 +9,22 @@ class Railtie < Rails::Railtie config.action_dispatch.best_standards_support = true config.action_dispatch.tld_length = 1 config.action_dispatch.ignore_accept_header = false - config.action_dispatch.rack_cache = {:metastore => "rails:/", :entitystore => "rails:/", :verbose => true} + config.action_dispatch.rescue_templates = { } + config.action_dispatch.rescue_responses = { } + + config.action_dispatch.rack_cache = { + :metastore => "rails:/", + :entitystore => "rails:/", + :verbose => true + } + initializer "action_dispatch.configure" do |app| ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length ActionDispatch::Request.ignore_accept_header = app.config.action_dispatch.ignore_accept_header + ActionDispatch::ShowExceptions.rescue_responses.merge!(config.action_dispatch.rescue_responses) + ActionDispatch::ShowExceptions.rescue_templates.merge!(config.action_dispatch.rescue_templates) + config.action_dispatch.always_write_cookie = Rails.env.development? if config.action_dispatch.always_write_cookie.nil? ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie end diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb index 47133e77e8bbbcd1f9e921eb8e3b89fd2041eda2..c2e31579a44adca62e765fa3497f65098e1bc75c 100644 --- a/activerecord/lib/active_record/railtie.rb +++ b/activerecord/lib/active_record/railtie.rb @@ -22,6 +22,13 @@ class Railtie < Rails::Railtie config.app_middleware.insert_after "::ActionDispatch::Callbacks", "ActiveRecord::ConnectionAdapters::ConnectionManagement" + config.action_dispatch.rescue_responses.merge!( + 'ActiveRecord::RecordNotFound' => :not_found, + 'ActiveRecord::StaleObjectError' => :conflict, + 'ActiveRecord::RecordInvalid' => :unprocessable_entity, + 'ActiveRecord::RecordNotSaved' => :unprocessable_entity + ) + rake_tasks do load "active_record/railties/databases.rake" end diff --git a/railties/test/application/middleware/show_exceptions_test.rb b/railties/test/application/middleware/show_exceptions_test.rb index 7dbadc6ce3df6fba2d43eec69e846e3b0bd8dff6..f3cae6a11e5367406f557c8794e0a106018b4632 100644 --- a/railties/test/application/middleware/show_exceptions_test.rb +++ b/railties/test/application/middleware/show_exceptions_test.rb @@ -16,6 +16,35 @@ def teardown teardown_app end + test "show exceptions middleware filter backtrace before logging" do + my_middleware = Struct.new(:app) do + def call(env) + raise "Failure" + end + end + + app.config.middleware.use my_middleware + + stringio = StringIO.new + Rails.logger = Logger.new(stringio) + + get "/" + assert_no_match(/action_dispatch/, stringio.string) + end + + test "renders active record exceptions as 404" do + my_middleware = Struct.new(:app) do + def call(env) + raise ActiveRecord::RecordNotFound + end + end + + app.config.middleware.use my_middleware + + get "/" + assert_equal 404, last_response.status + end + test "unspecified route when set action_dispatch.show_exceptions to false" do app.config.action_dispatch.show_exceptions = false diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb index 4703a59326401f8638282f5eb8adb5df0c360ab4..dba79bfd9668bd4a3d11590c13d3bb6e05e7cca5 100644 --- a/railties/test/application/middleware_test.rb +++ b/railties/test/application/middleware_test.rb @@ -104,7 +104,7 @@ def app assert !middleware.include?("ActionDispatch::Static") end - test "includes show exceptions even action_dispatch.show_exceptions is disabled" do + test "includes show exceptions even if action_dispatch.show_exceptions is disabled" do add_to_config "config.action_dispatch.show_exceptions = false" boot! assert middleware.include?("ActionDispatch::ShowExceptions") @@ -191,26 +191,6 @@ def index assert_equal nil, last_response.headers["Etag"] end - # Show exceptions middleware - test "show exceptions middleware filter backtrace before logging" do - my_middleware = Struct.new(:app) do - def call(env) - raise "Failure" - end - end - - make_basic_app do |app| - app.config.middleware.use my_middleware - end - - stringio = StringIO.new - Rails.logger = Logger.new(stringio) - - env = Rack::MockRequest.env_for("/") - Rails.application.call(env) - assert_no_match(/action_dispatch/, stringio.string) - end - private def boot!