Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow intercepting exceptions that are raised in ActionCable command #34917

Merged
merged 1 commit into from
Mar 20, 2020

Conversation

waymondo
Copy link
Contributor

Summary

Exceptions raised during command execution on an ActionCable Channel
are logged and suppressed, which does not allow for any sort of error
handling or reporting (via external services such as Bugsnag or Honeybadger).
This adds a simple hook to intercept the rescued exception on the ActionCable Connection.

Other Information

I had thought that maybe the default implementation of on_command_execution_exception should be the current logging behavior, but I opted for it being a no op. I'm happy to change it if that is preferable.

This is my first Rails PR so please let me know if there are any conventions that I should change about this patch.

@waymondo
Copy link
Contributor Author

Is there a way I could get a maintainer to weigh in on this PR?

@rails-bot
Copy link

rails-bot bot commented Dec 18, 2019

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
Thank you for your contributions.

@rails-bot rails-bot bot added the stale label Dec 18, 2019
@waymondo
Copy link
Contributor Author

Rails bot just reminded me this hasn't been addressed. I still think this is something that should be supported by ActionCable if not this exact PR. It would be great to get a Rails maintainer to weigh in

@rails-bot rails-bot bot removed the stale label Dec 18, 2019
@rails-bot
Copy link

rails-bot bot commented Mar 17, 2020

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
Thank you for your contributions.

@rails-bot rails-bot bot added the stale label Mar 17, 2020
@machty
Copy link
Contributor

machty commented Mar 17, 2020

This is a very useful contribution, could someone please take a look?

@rails-bot rails-bot bot removed the stale label Mar 17, 2020
Copy link
Member

@jeremy jeremy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @waymondo!

Let's use ActiveSupport::Rescuable.

Check out https://github.com/rails/rails/pull/34686/files for an example of the usage style.

@waymondo
Copy link
Contributor Author

Thanks @jeremy. That's an obvious improvement in retrospect. Just updated the PR.

Copy link
Member

@jeremy jeremy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good!

Noting that a Channel rescue_from would handle the exception example in the test case. In this sense, setting a Connection rescue_from is a convenient fallback, in addition to catching other unhandled exceptions.

Let's update the changelog as well!

@waymondo
Copy link
Contributor Author

Yeah, I only learned since you linked that PR as an example that the rescue_from mechanism was already in place for Channels. This is still helpful for global error reporting, but handling errors in the Channel is probably preferential in most cases. Added a changelog entry, but it might be good to describe these exception handling usages in https://guides.rubyonrails.org/action_cable_overview.html as well. Is there a repo for those, or how are those docs managed?

@jeremy
Copy link
Member

jeremy commented Mar 20, 2020

Same git repo! Guides can be updated alongside this PR, if you're interested: https://github.com/rails/rails/blob/master/guides/source/action_cable_overview.md

and update ActionCable guide to describe exception handling usage

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Your branch is behind 'origin/master' by 5 commits, and can be fast-forwarded.
#
# Changes to be committed:
#	modified:   actioncable/CHANGELOG.md
#	modified:   actioncable/lib/action_cable/connection/base.rb
#	modified:   actioncable/lib/action_cable/connection/subscriptions.rb
#	modified:   actioncable/test/connection/subscriptions_test.rb
#	modified:   guides/source/action_cable_overview.md
#
@waymondo
Copy link
Contributor Author

Cool, updated the guides and combined everything into a single commit. Let me know if there's anything else you'd like me to adjust.

@jeremy jeremy merged commit d2571e5 into rails:master Mar 20, 2020
@jeremy jeremy added this to the 6.1.0 milestone Mar 20, 2020
Copy link
Contributor

@rmacklin rmacklin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey folks, I noticed a typo in the newly added docs, so I've opened #38781 to address it.


By default, unhandled exceptions are caught and logged to Rails' logger. If you would like to
globally intercept these exceptions and report them to an external bug tracking service, for
example, you can do so with `rescue_with`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we got the method name and the with parameter mixed up:

Suggested change
example, you can do so with `rescue_with`.
example, you can do so with `rescue_from`.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks and sorry!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem!

#### Exception Handling

As with `ActionCable::Connection::Base`, you can also use
[`rescue_with`](https://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing here:

Suggested change
[`rescue_with`](https://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html)
[`rescue_from`](https://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html)

@agarcher
Copy link

agarcher commented Aug 19, 2021

I noticed that this implementation doesn't rescue exceptions raised in subscribed or unsubscribed, but only those in actions. I assume that's not by design because, as far as I can tell, there's no way to recover from exceptions in those flows.

Edit: Nevermind. I figured this out. For the subscribe/unsubscribe events, the rescue_from needs to be on the ActionCable::Connection::Base not the ActionCable::Channel::Base.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants