Class: GrapeRailsLogger::EndpointWrapper

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

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.



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) ⇒ Object



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
# 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
  start_time = Time.now
  Timings.reset_db_runtime

  # 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)
    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
    (response, env, payload, start_time)

    # Return the response - subscriber will log it
    response
  end
rescue => e
  # If notifications fail, still process the request
  handle_instrumentation_error(e)
  @app.call(env)
end