提交 a725a453 编写于 作者: K Kir Shatrov

Display exceptions in text format for xhr request

上级 998d9c89
* Development mode exceptions are rendered in text format in case of XHR request.
*Kir Shatrov*
* Fix an issue where :if and :unless controller action procs were being run
before checking for the correct action in the :only and :unless options.
......
......@@ -34,27 +34,35 @@ def render_exception(env, exception)
log_error(env, wrapper)
if env['action_dispatch.show_detailed_exceptions']
request = Request.new(env)
template = ActionView::Base.new([RESCUES_TEMPLATE_PATH],
:request => Request.new(env),
:exception => wrapper.exception,
:application_trace => wrapper.application_trace,
:framework_trace => wrapper.framework_trace,
:full_trace => wrapper.full_trace,
:routes_inspector => routes_inspector(exception),
:source_extract => wrapper.source_extract,
:line_number => wrapper.line_number,
:file => wrapper.file
request: request,
exception: wrapper.exception,
application_trace: wrapper.application_trace,
framework_trace: wrapper.framework_trace,
full_trace: wrapper.full_trace,
routes_inspector: routes_inspector(exception),
source_extract: wrapper.source_extract,
line_number: wrapper.line_number,
file: wrapper.file
)
file = "rescues/#{wrapper.rescue_template}"
body = template.render(:template => file, :layout => 'rescues/layout')
render(wrapper.status_code, body)
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)
else
raise exception
end
end
def render(status, body)
[status, {'Content-Type' => "text/html; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]]
def render(status, body, format)
[status, {'Content-Type' => "#{format}; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]]
end
def log_error(env, wrapper)
......
<%
clean_params = @request.filtered_parameters.clone
clean_params.delete("action")
clean_params.delete("controller")
request_dump = clean_params.empty? ? 'None' : clean_params.inspect.gsub(',', ",\n")
def debug_hash(object)
object.to_hash.sort_by { |k, _| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n")
end unless self.class.method_defined?(:debug_hash)
%>
Request parameters
<%= request_dump %>
Session dump
<%= debug_hash @request.session %>
Env dump
<%= debug_hash @request.env.slice(*@request.class::ENV_METHODS) %>
Response headers
<%= defined?(@response) ? @response.headers.inspect.gsub(',', ",\n") : 'None' %>
<%
traces = { "Application Trace" => @application_trace,
"Framework Trace" => @framework_trace,
"Full Trace" => @full_trace }
%>
Rails.root: <%= defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : "unset" %>
<% traces.each do |name, trace| %>
<% if trace.any? %>
<%= name %>
<%= trace.join("\n") %>
<% end %>
<% end %>
Routing Error
<%= @exception.message %>
<% unless @exception.failures.empty? %>
Failure reasons:
<% @exception.failures.each do |route, reason| %>
- <%= route.inspect.delete('\\') %></code> failed because <%= reason.downcase %>
<% end %>
<% end %>
<%= render template: "rescues/_trace", format: :text %>
<% @source_extract = @exception.source_extract(0, :html) %>
<%= @exception.original_exception.class.to_s %> in <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
Showing <%= @exception.file_name %> where line #<%= @exception.line_number %> raised:
<%= @exception.message %>
<%= @exception.sub_template_message %>
<%= render template: "rescues/_trace", format: :text %>
<%= render template: "rescues/_request_and_response", format: :text %>
......@@ -128,6 +128,47 @@ def setup
assert_match(/ActionController::ParameterMissing/, body)
end
test "rescue with text error for xhr request" do
@app = DevelopmentApp
xhr_request_env = {'action_dispatch.show_exceptions' => true, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'}
get "/", {}, xhr_request_env
assert_response 500
assert_no_match(/<body>/, body)
assert_equal response.content_type, "text/plain"
assert_match(/puke/, body)
get "/not_found", {}, xhr_request_env
assert_response 404
assert_no_match(/<body>/, body)
assert_equal response.content_type, "text/plain"
assert_match(/#{AbstractController::ActionNotFound.name}/, body)
get "/method_not_allowed", {}, xhr_request_env
assert_response 405
assert_no_match(/<body>/, body)
assert_equal response.content_type, "text/plain"
assert_match(/ActionController::MethodNotAllowed/, body)
get "/unknown_http_method", {}, xhr_request_env
assert_response 405
assert_no_match(/<body>/, body)
assert_equal response.content_type, "text/plain"
assert_match(/ActionController::UnknownHttpMethod/, body)
get "/bad_request", {}, xhr_request_env
assert_response 400
assert_no_match(/<body>/, body)
assert_equal response.content_type, "text/plain"
assert_match(/ActionController::BadRequest/, body)
get "/parameter_missing", {}, xhr_request_env
assert_response 400
assert_no_match(/<body>/, body)
assert_equal response.content_type, "text/plain"
assert_match(/ActionController::ParameterMissing/, body)
end
test "does not show filtered parameters" do
@app = DevelopmentApp
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册