mirror of https://github.com/rails/rails
ActionDispatch::Executor: report errors handled by ShowExceptions
Fix: https://github.com/rails/rails/issues/51002 In the default middleware stack, the `ShowExceptions` middleware is lower than `ActionDispatch::Execturor` and will handle most exceptions causing `Executor` not to witness any. Instead we need to rely on `action_dispatch.exception` being added into the request env.
This commit is contained in:
parent
9940dc879d
commit
4067c9565a
|
@ -14,6 +14,9 @@ module ActionDispatch
|
|||
state = @executor.run!(reset: true)
|
||||
begin
|
||||
response = @app.call(env)
|
||||
if rendered_error = env["action_dispatch.exception"]
|
||||
@executor.error_reporter.report(rendered_error, handled: false, source: "application.action_dispatch")
|
||||
end
|
||||
returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
|
||||
rescue => error
|
||||
@executor.error_reporter.report(error, handled: false, source: "application.action_dispatch")
|
||||
|
|
|
@ -34,8 +34,10 @@ module ActionDispatch
|
|||
request = ActionDispatch::Request.new env
|
||||
backtrace_cleaner = request.get_header("action_dispatch.backtrace_cleaner")
|
||||
wrapper = ExceptionWrapper.new(backtrace_cleaner, exception)
|
||||
request.set_header "action_dispatch.exception", wrapper.unwrapped_exception
|
||||
|
||||
if wrapper.show?(request)
|
||||
render_exception(request, wrapper)
|
||||
render_exception(request.dup, wrapper)
|
||||
else
|
||||
raise exception
|
||||
end
|
||||
|
@ -44,7 +46,6 @@ module ActionDispatch
|
|||
private
|
||||
def render_exception(request, wrapper)
|
||||
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)
|
||||
|
|
|
@ -119,6 +119,34 @@ class ExecutorTest < ActiveSupport::TestCase
|
|||
assert_equal requests_count - 1, completed
|
||||
end
|
||||
|
||||
def test_error_reporting
|
||||
raised_error = nil
|
||||
error_report = assert_error_reported do
|
||||
raised_error = assert_raises TypeError do
|
||||
call_and_return_body { 1 + "1" }
|
||||
end
|
||||
end
|
||||
assert_same raised_error, error_report.error
|
||||
end
|
||||
|
||||
def test_error_reporting_with_show_exception
|
||||
middleware = Rack::Lint.new(
|
||||
ActionDispatch::Executor.new(
|
||||
ActionDispatch::ShowExceptions.new(
|
||||
Rack::Lint.new(->(_env) { 1 + "1" }),
|
||||
->(_env) { [500, {}, ["Oops"]] },
|
||||
),
|
||||
executor,
|
||||
)
|
||||
)
|
||||
|
||||
env = Rack::MockRequest.env_for("", {})
|
||||
error_report = assert_error_reported do
|
||||
middleware.call(env)
|
||||
end
|
||||
assert_instance_of TypeError, error_report.error
|
||||
end
|
||||
|
||||
private
|
||||
def call_and_return_body(&block)
|
||||
app = block || proc { [200, {}, []] }
|
||||
|
|
Loading…
Reference in New Issue