Class: GrapeRailsLogger::EndpointWrapper

Inherits:
Object
  • Object
show all
Defined in:
lib/grape_rails_logger/endpoint_wrapper.rb,
sig/grape_rails_logger.rbs

Overview

Wraps the final Rack app returned by Grape::Endpoint#build_stack to capture the response AFTER Error middleware has fully processed it (including rescue_from handlers).

This is the correct place to log because:

  1. Error middleware wraps everything and processes exceptions
  2. rescue_from handlers run and set the correct status
  3. The final response is returned with the correct status
  4. We capture it here, AFTER all processing is complete

Instance Method Summary collapse

Constructor Details

#initialize(app, endpoint) ⇒ EndpointWrapper

Returns a new instance of EndpointWrapper.

Parameters:

  • app (Object)
  • endpoint (Object)


13
14
15
16
# File 'lib/grape_rails_logger/endpoint_wrapper.rb', line 13

def initialize(app, endpoint)
  @app = app
  @endpoint = endpoint
end

Instance Method Details

#call(env) ⇒ Array[Integer, Hash[String, String], Array[String]]

Parameters:

  • env (Hash[String, untyped])

Returns:

  • (Array[Integer, Hash[String, String], Array[String]])


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/grape_rails_logger/endpoint_wrapper.rb', line 18

def call(env)
  return @app.call(env) unless GrapeRailsLogger.effective_config.enabled

  logger = resolve_logger
  downstream_response = nil

  Timings.track_grape_request do
    # Wrap the entire request in ActiveSupport::Notifications
    # This ensures we capture the final response AFTER Error middleware processes exceptions
    ActiveSupport::Notifications.instrument("grape.request", env: env, logger: logger) do |payload|
      # Call the wrapped app - Error middleware will process exceptions and return final response
      # NOTE: We do NOT read the body here - Grape will process it and parse params
      # We'll extract params later from already-parsed sources (endpoint.request.params)
      downstream_response = @app.call(env)

      # NOW collect all data AFTER Error middleware has processed exceptions
      # At this point, response contains the final Rack response with correct status
      # AND Grape has already parsed the params, so we can safely access endpoint.request.params
      (downstream_response, env, payload)

      # Return the response - subscriber will log it
      downstream_response
    end
  end
rescue => e
  handle_instrumentation_error(e)
  return downstream_response if downstream_response

  @app.call(env)
end