From 5359262695b491422b18c565567e16ad50f6155e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 16 Dec 2011 09:59:36 +0100 Subject: ShowExceptions should understand X-Cascade responses from exceptions app. --- .../action_dispatch/middleware/debug_exceptions.rb | 1 - .../action_dispatch/middleware/public_exceptions.rb | 2 +- .../lib/action_dispatch/middleware/show_exceptions.rb | 19 +++++++++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb index 3904183823..dabbabb1e6 100644 --- a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb @@ -15,7 +15,6 @@ module ActionDispatch begin response = @app.call(env) - # TODO: Maybe this should be in the router itself if response[1]['X-Cascade'] == 'pass' body = response[2] body.close if body.respond_to?(:close) diff --git a/actionpack/lib/action_dispatch/middleware/public_exceptions.rb b/actionpack/lib/action_dispatch/middleware/public_exceptions.rb index 6600d6232e..85b8d178bf 100644 --- a/actionpack/lib/action_dispatch/middleware/public_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/public_exceptions.rb @@ -17,7 +17,7 @@ module ActionDispatch elsif File.exist?(path) render(status, File.read(path)) else - render(status, '') + [404, { "X-Cascade" => "pass" }, []] end end diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index 5323048d90..5eceeece1f 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -4,12 +4,17 @@ require 'active_support/deprecation' module ActionDispatch # This middleware rescues any exception returned by the application - # and calls a rack application that will wrap it in a format for the end user. + # and calls an exceptions app that will wrap it in a format for the end user. # - # The rack application should be passed as parameter on initialization + # The exceptions app should be passed as parameter on initialization # of ShowExceptions. Everytime there is an exception, ShowExceptions will # store the exception in env["action_dispatch.exception"], rewrite the # PATH_INFO to the exception status code and call the rack app. + # + # If the application returns a "X-Cascade" pass response, this middleware + # will send an empty response as result with the correct status code. + # If any exception happens inside the exceptions app, this middleware + # catches the exceptions and returns a FAILSAFE_RESPONSE. class ShowExceptions FAILSAFE_RESPONSE = [500, {'Content-Type' => 'text/html'}, ["

500 Internal Server Error

" << @@ -65,12 +70,18 @@ module ActionDispatch def render_exception(env, exception) wrapper = ExceptionWrapper.new(env, exception) + status = wrapper.status_code env["action_dispatch.exception"] = wrapper.exception - env["PATH_INFO"] = "/#{wrapper.status_code}" - @exceptions_app.call(env) + env["PATH_INFO"] = "/#{status}" + response = @exceptions_app.call(env) + response[1]['X-Cascade'] == 'pass' ? pass_response(status) : response rescue Exception => failsafe_error $stderr.puts "Error during failsafe response: #{failsafe_error}\n #{failsafe_error.backtrace * "\n "}" FAILSAFE_RESPONSE end + + def pass_response(status) + [status, {"Content-Type" => "text/html; charset=#{Response.default_charset}", "Content-Length" => "0"}, []] + end end end -- cgit v1.2.3