diff --git a/actionpack/lib/action_dispatch/middleware/executor.rb b/actionpack/lib/action_dispatch/middleware/executor.rb index e0c4b898fe0..ae76d8de167 100644 --- a/actionpack/lib/action_dispatch/middleware/executor.rb +++ b/actionpack/lib/action_dispatch/middleware/executor.rb @@ -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") diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index b1a19d793f1..bc95cd79ab1 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -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) diff --git a/actionpack/test/dispatch/executor_test.rb b/actionpack/test/dispatch/executor_test.rb index 3dce849e9c5..fe0e8799629 100644 --- a/actionpack/test/dispatch/executor_test.rb +++ b/actionpack/test/dispatch/executor_test.rb @@ -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, {}, []] }