diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/middleware/debug_exceptions.rb')
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/debug_exceptions.rb | 222 |
1 files changed, 114 insertions, 108 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb index 8974258cf7..1c720c5a8e 100644 --- a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb @@ -1,16 +1,16 @@ -require 'action_dispatch/http/request' -require 'action_dispatch/middleware/exception_wrapper' -require 'action_dispatch/routing/inspector' -require 'action_view' -require 'action_view/base' +require "action_dispatch/http/request" +require "action_dispatch/middleware/exception_wrapper" +require "action_dispatch/routing/inspector" +require "action_view" +require "action_view/base" -require 'pp' +require "pp" module ActionDispatch # This middleware is responsible for logging exceptions and # showing a debugging page in case the request is local. class DebugExceptions - RESCUES_TEMPLATE_PATH = File.expand_path('../templates', __FILE__) + RESCUES_TEMPLATE_PATH = File.expand_path("../templates", __FILE__) class DebugView < ActionView::Base def debug_params(params) @@ -19,7 +19,7 @@ module ActionDispatch clean_params.delete("controller") if clean_params.empty? - 'None' + "None" else PP.pp(clean_params, "", 200) end @@ -27,9 +27,9 @@ module ActionDispatch def debug_headers(headers) if headers.present? - headers.inspect.gsub(',', ",\n") + headers.inspect.gsub(",", ",\n") else - 'None' + "None" end end @@ -38,7 +38,9 @@ module ActionDispatch end def render(*) - if logger = ActionView::Base.logger + logger = ActionView::Base.logger + + if logger && logger.respond_to?(:silence) logger.silence { super } else super @@ -56,7 +58,7 @@ module ActionDispatch request = ActionDispatch::Request.new env _, headers, body = response = @app.call(env) - if headers['X-Cascade'] == 'pass' + if headers["X-Cascade"] == "pass" body.close if body.respond_to?(:close) raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}" end @@ -69,129 +71,133 @@ module ActionDispatch private - def render_exception(request, exception) - backtrace_cleaner = request.get_header('action_dispatch.backtrace_cleaner') - wrapper = ExceptionWrapper.new(backtrace_cleaner, exception) - log_error(request, wrapper) + def render_exception(request, exception) + backtrace_cleaner = request.get_header("action_dispatch.backtrace_cleaner") + wrapper = ExceptionWrapper.new(backtrace_cleaner, exception) + log_error(request, wrapper) - if request.get_header('action_dispatch.show_detailed_exceptions') - content_type = request.formats.first + if request.get_header("action_dispatch.show_detailed_exceptions") + content_type = request.formats.first - if api_request?(content_type) - render_for_api_request(content_type, wrapper) + if api_request?(content_type) + render_for_api_request(content_type, wrapper) + else + render_for_browser_request(request, wrapper) + end else - render_for_browser_request(request, wrapper) + raise exception end - else - raise exception end - end - def render_for_browser_request(request, wrapper) - template = create_template(request, wrapper) - file = "rescues/#{wrapper.rescue_template}" + def render_for_browser_request(request, wrapper) + template = create_template(request, wrapper) + file = "rescues/#{wrapper.rescue_template}" - if request.xhr? - body = template.render(template: file, layout: false, formats: [:text]) - format = "text/plain" - else - body = template.render(template: file, layout: 'rescues/layout') - format = "text/html" + if request.xhr? + body = template.render(template: file, layout: false, formats: [:text]) + format = "text/plain" + else + body = template.render(template: file, layout: "rescues/layout") + format = "text/html" + end + render(wrapper.status_code, body, format) end - render(wrapper.status_code, body, format) - end - - def render_for_api_request(content_type, wrapper) - body = { - status: wrapper.status_code, - error: Rack::Utils::HTTP_STATUS_CODES.fetch( - wrapper.status_code, - Rack::Utils::HTTP_STATUS_CODES[500] - ), - exception: wrapper.exception.inspect, - traces: wrapper.traces - } - to_format = "to_#{content_type.to_sym}" + def render_for_api_request(content_type, wrapper) + body = { + status: wrapper.status_code, + error: Rack::Utils::HTTP_STATUS_CODES.fetch( + wrapper.status_code, + Rack::Utils::HTTP_STATUS_CODES[500] + ), + exception: wrapper.exception.inspect, + traces: wrapper.traces + } + + to_format = "to_#{content_type.to_sym}" + + if content_type && body.respond_to?(to_format) + formatted_body = body.public_send(to_format) + format = content_type + else + formatted_body = body.to_json + format = Mime[:json] + end - if content_type && body.respond_to?(to_format) - formatted_body = body.public_send(to_format) - format = content_type - else - formatted_body = body.to_json - format = Mime[:json] + render(wrapper.status_code, formatted_body, format) end - render(wrapper.status_code, formatted_body, format) - end + def create_template(request, wrapper) + traces = wrapper.traces - def create_template(request, wrapper) - traces = wrapper.traces + trace_to_show = "Application Trace" + if traces[trace_to_show].empty? && wrapper.rescue_template != "routing_error" + trace_to_show = "Full Trace" + end - trace_to_show = 'Application Trace' - if traces[trace_to_show].empty? && wrapper.rescue_template != 'routing_error' - trace_to_show = 'Full Trace' - end + if source_to_show = traces[trace_to_show].first + source_to_show_id = source_to_show[:id] + end - if source_to_show = traces[trace_to_show].first - source_to_show_id = source_to_show[:id] + DebugView.new([RESCUES_TEMPLATE_PATH], + request: request, + exception: wrapper.exception, + traces: traces, + show_source_idx: source_to_show_id, + trace_to_show: trace_to_show, + routes_inspector: routes_inspector(wrapper.exception), + source_extracts: wrapper.source_extracts, + line_number: wrapper.line_number, + file: wrapper.file + ) end - DebugView.new([RESCUES_TEMPLATE_PATH], - request: request, - exception: wrapper.exception, - traces: traces, - show_source_idx: source_to_show_id, - trace_to_show: trace_to_show, - routes_inspector: routes_inspector(wrapper.exception), - source_extracts: wrapper.source_extracts, - line_number: wrapper.line_number, - file: wrapper.file - ) - end - - def render(status, body, format) - [status, {'Content-Type' => "#{format}; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]] - end + def render(status, body, format) + [status, { "Content-Type" => "#{format}; charset=#{Response.default_charset}", "Content-Length" => body.bytesize.to_s }, [body]] + end - def log_error(request, wrapper) - logger = logger(request) - return unless logger + def log_error(request, wrapper) + logger = logger(request) + return unless logger - exception = wrapper.exception + exception = wrapper.exception - trace = wrapper.application_trace - trace = wrapper.framework_trace if trace.empty? + trace = wrapper.application_trace + trace = wrapper.framework_trace if trace.empty? - ActiveSupport::Deprecation.silence do - logger.fatal " " - logger.fatal "#{exception.class} (#{exception.message}):" - log_array logger, exception.annoted_source_code if exception.respond_to?(:annoted_source_code) - logger.fatal " " - log_array logger, trace + ActiveSupport::Deprecation.silence do + logger.fatal " " + logger.fatal "#{exception.class} (#{exception.message}):" + log_array logger, exception.annoted_source_code if exception.respond_to?(:annoted_source_code) + logger.fatal " " + log_array logger, trace + end end - end - def log_array(logger, array) - array.map { |line| logger.fatal line } - end + def log_array(logger, array) + if logger.formatter && logger.formatter.respond_to?(:tags_text) + logger.fatal array.join("\n#{logger.formatter.tags_text}") + else + logger.fatal array.join("\n") + end + end - def logger(request) - request.logger || ActionView::Base.logger || stderr_logger - end + def logger(request) + request.logger || ActionView::Base.logger || stderr_logger + end - def stderr_logger - @stderr_logger ||= ActiveSupport::Logger.new($stderr) - end + def stderr_logger + @stderr_logger ||= ActiveSupport::Logger.new($stderr) + end - def routes_inspector(exception) - if @routes_app.respond_to?(:routes) && (exception.is_a?(ActionController::RoutingError) || exception.is_a?(ActionView::Template::Error)) - ActionDispatch::Routing::RoutesInspector.new(@routes_app.routes.routes) + def routes_inspector(exception) + if @routes_app.respond_to?(:routes) && (exception.is_a?(ActionController::RoutingError) || exception.is_a?(ActionView::Template::Error)) + ActionDispatch::Routing::RoutesInspector.new(@routes_app.routes.routes) + end end - end - def api_request?(content_type) - @response_format == :api && !content_type.html? - end + def api_request?(content_type) + @response_format == :api && !content_type.html? + end end end |