Object
This middleware rescues any exception returned by the application and renders nice exception pages if it’s being rescued locally.
# File lib/action_dispatch/middleware/show_exceptions.rb, line 45 45: def call(env) 46: status, headers, body = @app.call(env) 47: 48: # Only this middleware cares about RoutingError. So, let's just raise 49: # it here. 50: # TODO: refactor this middleware to handle the X-Cascade scenario without 51: # having to raise an exception. 52: if headers['X-Cascade'] == 'pass' 53: raise ActionController::RoutingError, "No route matches #{env['PATH_INFO'].inspect}" 54: end 55: 56: [status, headers, body] 57: rescue Exception => exception 58: raise exception if env['action_dispatch.show_exceptions'] == false 59: render_exception(env, exception) 60: end
# File lib/action_dispatch/middleware/show_exceptions.rb, line 136 136: def application_trace(exception) 137: clean_backtrace(exception, :silent) 138: end
# File lib/action_dispatch/middleware/show_exceptions.rb, line 148 148: def clean_backtrace(exception, *args) 149: defined?(Rails) && Rails.respond_to?(:backtrace_cleaner) ? 150: Rails.backtrace_cleaner.clean(exception.backtrace, *args) : 151: exception.backtrace 152: end
# File lib/action_dispatch/middleware/show_exceptions.rb, line 140 140: def framework_trace(exception) 141: clean_backtrace(exception, :noise) 142: end
# File lib/action_dispatch/middleware/show_exceptions.rb, line 144 144: def full_trace(exception) 145: clean_backtrace(exception, :all) 146: end
# File lib/action_dispatch/middleware/show_exceptions.rb, line 125 125: def log_error(exception) 126: return unless logger 127: 128: ActiveSupport::Deprecation.silence do 129: message = "\n#{exception.class} (#{exception.message}):\n" 130: message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) 131: message << " " << application_trace(exception).join("\n ") 132: logger.fatal("#{message}\n\n") 133: end 134: end
# File lib/action_dispatch/middleware/show_exceptions.rb, line 154 154: def logger 155: defined?(Rails.logger) ? Rails.logger : Logger.new($stderr) 156: end
# File lib/action_dispatch/middleware/show_exceptions.rb, line 121 121: def public_path 122: defined?(Rails.public_path) ? Rails.public_path : 'public_path' 123: end
# File lib/action_dispatch/middleware/show_exceptions.rb, line 117 117: def render(status, body) 118: [status, {'Content-Type' => 'text/html', 'Content-Length' => body.bytesize.to_s}, [body]] 119: end
# File lib/action_dispatch/middleware/show_exceptions.rb, line 63 63: def render_exception(env, exception) 64: log_error(exception) 65: 66: request = Request.new(env) 67: if @consider_all_requests_local || request.local? 68: rescue_action_locally(request, exception) 69: else 70: rescue_action_in_public(exception) 71: end 72: rescue Exception => failsafe_error 73: $stderr.puts "Error during failsafe response: #{failsafe_error}\n #{failsafe_error.backtrace * "\n "}" 74: FAILSAFE_RESPONSE 75: end
Attempts to render a static error page based on the status_code thrown, or just return headers if no such file exists. At first, it will try to render a localized static page. For example, if a 500 error is being handled Rails and locale is :da, it will first attempt to render the file at public/500.da.html then attempt to render public/500.html. If none of them exist, the body of the response will be left empty.
# File lib/action_dispatch/middleware/show_exceptions.rb, line 99 99: def rescue_action_in_public(exception) 100: status = status_code(exception) 101: locale_path = "#{public_path}/#{status}.#{I18n.locale}.html" if I18n.locale 102: path = "#{public_path}/#{status}.html" 103: 104: if locale_path && File.exist?(locale_path) 105: render(status, File.read(locale_path)) 106: elsif File.exist?(path) 107: render(status, File.read(path)) 108: else 109: render(status, '') 110: end 111: end
Render detailed diagnostics for unhandled exceptions rescued from a controller action.
# File lib/action_dispatch/middleware/show_exceptions.rb, line 79 79: def rescue_action_locally(request, exception) 80: template = ActionView::Base.new([RESCUES_TEMPLATE_PATH], 81: :request => request, 82: :exception => exception, 83: :application_trace => application_trace(exception), 84: :framework_trace => framework_trace(exception), 85: :full_trace => full_trace(exception) 86: ) 87: file = "rescues/#{@@rescue_templates[exception.class.name]}.erb" 88: body = template.render(:file => file, :layout => 'rescues/layout.erb') 89: render(status_code(exception), body) 90: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.