fix(rails): make Action Cable handle_open/handle_close overrides public for Rails 8.2#2972
Conversation
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>
|
Independently confirmed on Rails The upgrade returns |
solnic
left a comment
There was a problem hiding this comment.
Thanks for tackling this. I left some comments but let's hold off with this until we have a beta released, so that we can add it to the CI matrix, which would help over here.
| end | ||
|
|
||
| module Connection | ||
| private |
There was a problem hiding this comment.
We need to do this conditionally, otherwise on older Rails version we'd be changing method visibility, and that would be an unwanted side-effect.
| expect(Sentry::Rails::ActionCableExtensions::Connection.public_method_defined?(:handle_open)).to eq(true) | ||
| expect(Sentry::Rails::ActionCableExtensions::Connection.public_method_defined?(:handle_close)).to eq(true) | ||
| end | ||
| end |
There was a problem hiding this comment.
This tests implementation details. I assume that under Rails 8.2 some of our specs would fail, right? If they do, then this test is redundant, if they don't, then it would be good to reproduce the issue under 8.2 by exercising the actual behavior that Sentry adds.
| ### Bug Fixes 🐛 | ||
|
|
||
| - (rails) Make Action Cable `handle_open`/`handle_close` overrides public so Rails 8.2's `ActionCable::Server::Socket` can invoke them ([rails/rails#50979](https://github.com/rails/rails/pull/50979)); the private overrides raised `NoMethodError` on every cable connection, killing all websocket traffic | ||
|
|
There was a problem hiding this comment.
No need to update this as CHANGELOG is now updated automatically during the release process 🪄
Description
Rails 8.2 decoupled the Action Cable connection from the socket in rails/rails#50979 (merged 2026-05-28):
ActionCable::Server::Socketnow invokesconnection.handle_openandconnection.handle_closefrom outside the connection object.Sentry::Rails::ActionCableExtensions::Connectiondeclares itshandle_open/handle_closeoverrides asprivate, which shadows the (public) framework methods through the prepend chain. On Rails main / 8.2, every cable connection then raises:before the
welcomemessage is sent. The practical effect is severe and silent: the WebSocket upgrade succeeds (101), but clients never receivewelcomeor 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:
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.