class ActionDispatch::ShowExceptions
This middleware rescues any exception returned by the application and calls an exceptions app that will wrap it in a format for the end user.
The exceptions app should be passed as parameter on initialization of ShowExceptions
. Every time there is an exception, ShowExceptions
will store the exception in env, 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.
Public Class Methods
new(app, exceptions_app)
click to toggle source
# File lib/action_dispatch/middleware/show_exceptions.rb, line 19 def initialize(app, exceptions_app) @app = app @exceptions_app = exceptions_app end
Public Instance Methods
call(env)
click to toggle source
# File lib/action_dispatch/middleware/show_exceptions.rb, line 24 def call(env) request = ActionDispatch::Request.new env @app.call(env) rescue Exception => exception if request.show_exceptions? render_exception(request, exception) else raise exception end end
Private Instance Methods
fallback_to_html_format_if_invalid_mime_type(request)
click to toggle source
# File lib/action_dispatch/middleware/show_exceptions.rb, line 58 def fallback_to_html_format_if_invalid_mime_type(request) # If the MIME type for the request is invalid then the # @exceptions_app may not be able to handle it. To make it # easier to handle, we switch to HTML. request.formats rescue ActionDispatch::Http::MimeNegotiation::InvalidType request.set_header "HTTP_ACCEPT", "text/html" end
pass_response(status)
click to toggle source
# File lib/action_dispatch/middleware/show_exceptions.rb, line 67 def pass_response(status) [status, { "Content-Type" => "text/html; charset=#{Response.default_charset}", "Content-Length" => "0" }, []] end
render_exception(request, exception)
click to toggle source
# File lib/action_dispatch/middleware/show_exceptions.rb, line 36 def render_exception(request, exception) backtrace_cleaner = request.get_header "action_dispatch.backtrace_cleaner" wrapper = ExceptionWrapper.new(backtrace_cleaner, exception) status = wrapper.status_code request.set_header "action_dispatch.exception", wrapper.unwrapped_exception request.set_header "action_dispatch.original_path", request.path_info request.set_header "action_dispatch.original_request_method", request.raw_request_method fallback_to_html_format_if_invalid_mime_type(request) request.path_info = "/#{status}" request.request_method = "GET" response = @exceptions_app.call(request.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 "}" [500, { "Content-Type" => "text/plain" }, ["500 Internal Server Error\n" \ "If you are the administrator of this website, then please read this web " \ "application's log file and/or the web server's log file to find out what " \ "went wrong."]] end