Class: Dispatch::Rails::ResponseAnnotator

Inherits:
Object
  • Object
show all
Defined in:
lib/dispatch/rails/response_annotator.rb

Overview

Opt-in Rack middleware (config.structured_error_responses). On 4xx/5xx responses it stamps the Rails request id — and, when a report base URL is known, a report URL — into response headers, and optionally into JSON error bodies. This is the API-only analogue of the bug-report widget: it hands the caller a correlation id they can quote when filing a curated report, which the Dispatch server then links back to the auto-captured error.

It is mounted just outside ActionDispatch::ShowExceptions so it sees the FINAL rendered error response — whether the app rescued the error itself (a normal 4xx) or it propagated and ShowExceptions rendered the 500. It never changes the status code, never swallows a propagating exception, and passes through untouched anything it cannot safely parse.

Constant Summary collapse

HEADER_REQUEST_ID =

Lowercase header names for Rack 3 conformance. HTTP header names are case-insensitive to clients, so emitting them lowercase changes nothing the caller sees, while satisfying Rack 3’s lowercase-only requirement.

"x-dispatch-request-id"
HEADER_REPORT_URL =
"x-dispatch-report-url"
BODY_REQUEST_ID =
"dispatch_request_id"
BODY_REPORT_URL =
"dispatch_report_url"

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ ResponseAnnotator

Returns a new instance of ResponseAnnotator.



27
28
29
# File 'lib/dispatch/rails/response_annotator.rb', line 27

def initialize(app)
  @app = app
end

Instance Method Details

#call(env) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/dispatch/rails/response_annotator.rb', line 31

def call(env)
  # @app.call is deliberately outside the rescue: if ShowExceptions re-raises
  # (e.g. show_exceptions disabled, or in tests), the exception must keep
  # propagating — we never swallow it.
  status, headers, body = @app.call(env)
  begin
    annotate(env, status, headers, body)
  rescue StandardError => e
    warn "[dispatch-rails] response annotation failed: #{e.class}: #{e.message}"
    [status, headers, body]
  end
end