Class: Realuptime::Errors::RackMiddleware

Inherits:
Object
  • Object
show all
Defined in:
lib/realuptime/errors/rack.rb

Overview

Plain Rack middleware: captures an exception escaping the app below it with the default minimal request context (method, path; the status is unknown mid-flight and omitted rather than guessed), then RE-RAISES. The middleware reports; the server keeps deciding what a 500 looks like. Never headers, never cookies, never bodies: the request capture is the same minimal default the JS and Python SDKs use.

use Realuptime::Errors::RackMiddleware

Also reports an exception a downstream framework swallowed into env / env (Rails's ShowExceptions sets the latter when it renders its own error page), so a Rails 500 that never propagates still gets captured. The same exception object is reported once, not twice.

Zero-dependency: this file never requires "rack"; a Rack app is any object answering call(env).

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ RackMiddleware

Returns a new instance of RackMiddleware.



23
24
25
# File 'lib/realuptime/errors/rack.rb', line 23

def initialize(app)
  @app = app
end

Class Method Details

.request_context(env) ⇒ Object

Method + path from a Rack env, nothing else. Shared with the Rails and Sidekiq integrations so every entry point captures identically.



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/realuptime/errors/rack.rb', line 58

def self.request_context(env)
  return nil unless env.is_a?(Hash)

  request = {}
  method = env["REQUEST_METHOD"]
  request["method"] = method.to_s if method
  path = env["PATH_INFO"]
  path = "#{env["SCRIPT_NAME"]}#{path}" if env["SCRIPT_NAME"] && !env["SCRIPT_NAME"].to_s.empty?
  request["path"] = path.to_s if path
  request.empty? ? nil : request
rescue StandardError
  nil
end

Instance Method Details

#call(env) ⇒ Object



27
28
29
30
31
32
33
34
35
# File 'lib/realuptime/errors/rack.rb', line 27

def call(env)
  response = @app.call(env)
  swallowed = env["action_dispatch.exception"] || env["rack.exception"]
  report(swallowed, env) if swallowed.is_a?(Exception)
  response
rescue Exception => e # rubocop:disable Lint/RescueException
  report(e, env)
  raise
end