Skip to content

fix(rails): make Action Cable handle_open/handle_close overrides public for Rails 8.2#2972

Open
kylekeesling wants to merge 1 commit into
getsentry:masterfrom
kylekeesling:fix/action-cable-handle-open-visibility
Open

fix(rails): make Action Cable handle_open/handle_close overrides public for Rails 8.2#2972
kylekeesling wants to merge 1 commit into
getsentry:masterfrom
kylekeesling:fix/action-cable-handle-open-visibility

Conversation

@kylekeesling

Copy link
Copy Markdown

Description

Rails 8.2 decoupled the Action Cable connection from the socket in rails/rails#50979 (merged 2026-05-28): ActionCable::Server::Socket now invokes connection.handle_open and connection.handle_close from outside the connection object.

Sentry::Rails::ActionCableExtensions::Connection declares its handle_open/handle_close overrides as private, which shadows the (public) framework methods through the prepend chain. On Rails main / 8.2, every cable connection then raises:

NoMethodError (private method 'handle_open' called for an instance of ApplicationCable::Connection)
  actioncable/lib/action_cable/server/socket.rb:127:in 'ActionCable::Server::Socket#handle_open'

before the welcome message is sent. The practical effect is severe and silent: the WebSocket upgrade succeeds (101), but clients never receive welcome or pings, so they treat the connection as stale and reconnect in a loop forever — no broadcasts (e.g. Turbo Streams) are ever delivered. The exception only hits the Rails logger, not Sentry, since it occurs in the instrumentation wrapper itself.

We hit this in production on a Rails edge app with sentry-rails 6.6.0 and confirmed the root cause by inspecting method visibility:

ApplicationCable::Connection.instance_method(:handle_open).owner
# => Sentry::Rails::ActionCableExtensions::Connection
ApplicationCable::Connection.private_method_defined?(:handle_open)
# => true

Fix

Make the two overrides public. On Rails < 8.2 they are only invoked internally on self (visibility is irrelevant there), so this is safe across all supported Rails versions. Added a regression spec asserting the visibility and a changelog entry.

bundle exec rspec spec/sentry/rails/action_cable_spec.rb → 12 examples, 0 failures.

Rails 8.2 decoupled the Action Cable connection from the socket
(rails/rails#50979): ActionCable::Server::Socket now invokes
connection.handle_open and connection.handle_close from outside the
connection. sentry-rails' prepended overrides were private, so on Rails
main every cable connection raises

  NoMethodError (private method 'handle_open' called for an instance of
  ApplicationCable::Connection)

before the welcome message is sent — clients never receive pings or
broadcasts and reconnect in a loop. The error only reaches the Rails
logger (Sentry isn't initialized for the failing connection path), so
it fails silently.

On Rails < 8.2 these methods are only called internally on self, where
visibility doesn't matter, so making them public is safe everywhere.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kylekeesling kylekeesling marked this pull request as ready for review June 11, 2026 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant