Class: Findbug::Capture::Middleware

Inherits:
Object
  • Object
show all
Defined in:
lib/findbug/capture/middleware.rb

Overview

Middleware captures uncaught exceptions at the Rack level.

WHY MIDDLEWARE + SUBSCRIBER?

You might wonder: “We already have ExceptionSubscriber. Why middleware?”

The subscriber catches errors reported via Rails.error, but:

  1. Not all Rails errors go through Rails.error

  2. Errors in middleware (before Rails) don’t hit the subscriber

  3. Some gems raise directly without using Rails.error

The middleware is a safety net that catches EVERYTHING at the Rack level.

MIDDLEWARE ORDER

We’re inserted AFTER ActionDispatch::ShowExceptions:

[Rack Stack]
...
ActionDispatch::ShowExceptions  ← Converts exceptions to 500 pages
Findbug::Capture::Middleware    ← WE ARE HERE
...
YourController

When an exception bubbles up:

  1. Controller raises

  2. WE catch it first, capture it, then re-raise

  3. ShowExceptions catches it and renders 500 page

We capture and RE-RAISE so Rails can still do its thing.

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ Middleware

Returns a new instance of Middleware.



44
45
46
# File 'lib/findbug/capture/middleware.rb', line 44

def initialize(app)
  @app = app
end

Instance Method Details

#call(env) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/findbug/capture/middleware.rb', line 48

def call(env)
  # Skip if Findbug is disabled
  return @app.call(env) unless Findbug.enabled?

  # Set up request context
  setup_context(env)

  # Call the next middleware/app
  response = @app.call(env)

  # Capture any error that was stored in the environment
  # (Some Rails error handlers store the error but don't re-raise)
  capture_env_exception(env)

  response
rescue Exception => e # rubocop:disable Lint/RescueException
  # Capture the exception
  capture_exception(e, env)

  # Re-raise so Rails can handle it (show 500 page, etc.)
  raise
ensure
  # Always clean up context
  Context.clear!
end