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

ActionCable probably doesn't work #470

Closed
nateberkopec opened this issue Feb 25, 2016 · 17 comments · Fixed by #1638
Closed

ActionCable probably doesn't work #470

nateberkopec opened this issue Feb 25, 2016 · 17 comments · Fixed by #1638

Comments

@nateberkopec
Copy link
Contributor

Just realized we probably aren't catching ActionCable exceptions, need to confirm/fix

@nateberkopec
Copy link
Contributor Author

nateberkopec commented Mar 11, 2016

Yikes, looks like we haven't looked at ActiveJob in a while either.

EDIT: Fixed this since I commented.

@danielschwartz
Copy link

@nateberkopec any ideas if this is being actively developed? I've wrapped most of my ActionCable channel methods, so Sentry is catching what it needs, but native support for this would be awesome.

@nateberkopec nateberkopec modified the milestone: 2.2.0 Sep 27, 2016
@nateberkopec nateberkopec modified the milestone: 2.2.0 Nov 22, 2016
@greatghoul
Copy link

any updates?

@aert
Copy link

aert commented Jul 23, 2017

I confirm that actioncable exceptions are not being reported on Rails 5.1.2 and sentry-raven 2.5.3

@nateberkopec
Copy link
Contributor Author

Thanks for all the comments, folks. I'll work on this next.

@aert
Copy link

aert commented Aug 7, 2017

Thanks @nateberkopec , keep up the nice work on this and the techemporwer bench ;)

@nateberkopec nateberkopec added this to the 2.7.0 milestone Aug 7, 2017
@kalv
Copy link

kalv commented Oct 5, 2017

@nateberkopec Anything I can do to help on this?

@tak1n
Copy link

tak1n commented Jan 24, 2018

@nateberkopec any news on this or a way I can help out?

It seems like actioncable is rescuing from Exception and just logging whatever happened:

https://github.com/rails/rails/blob/5.1.3/actioncable/lib/action_cable/connection/subscriptions.rb#L21

@nachoal
Copy link

nachoal commented Aug 19, 2019

@nateberkopec Would love to help out with this, searching for a way to catch subscription errors for ActionCable

@nateberkopec
Copy link
Contributor Author

👋 Hello all, I no longer maintain raven-ruby.

However, what you're looking for is some kind of "middleware" concept for ActionCable. What you need is a way to wrap Sentry "around" an ActionCable response. I'm sure there's ways to do this, I just have no experience with it. After that, simply write up a PR + some tests. Shouldn't be too bad.

@st0012 st0012 modified the milestones: 2.7.0, 3.1.0 Aug 10, 2020
@st0012 st0012 added this to Low priority in 3.x Aug 28, 2020
@st0012 st0012 modified the milestones: 3.1.0, 4.0.0 Sep 3, 2020
@st0012 st0012 added this to To do in 4.x via automation Sep 3, 2020
@st0012 st0012 removed this from Low priority in 3.x Sep 3, 2020
@agrobbin
Copy link
Contributor

I recently ran into this, wanting Sentry integration into Action Cable, and ended up implementing it like this:

module Raven
  module Integrations
    module ActionCable
      class ExceptionReporter
        TRANSACTION_PREFIX = 'ActionCable'

        def self.capture(env, transaction_name:, extra_context: nil, &block)
          Raven.rack_context(env)
          Raven.extra_context(action_cable: extra_context) if extra_context
          Raven.context.transaction.push [TRANSACTION_PREFIX, transaction_name].join('/')

          block.call
        rescue Exception => e # rubocop:disable Lint/RescueException
          Raven.capture_exception(e)

          raise
        ensure
          Raven.context.transaction.pop
          Raven::Context.clear!
        end
      end

      module Channel
        module Subscriptions
          extend ActiveSupport::Concern

          included do
            set_callback :subscribe, :around, ->(_, block) { raven_capture(:subscribe, &block) }, prepend: true
            set_callback :unsubscribe, :around, ->(_, block) { raven_capture(:unsubscribe, &block) }, prepend: true
          end

          private

          def raven_capture(hook, &block)
            extra_context = { params: params }

            ExceptionReporter.capture(connection.env, transaction_name: "#{self.class.name}##{hook}", extra_context: extra_context, &block)
          end
        end

        module Actions
          private

          def dispatch_action(action, data)
            extra_context = { params: params, data: data }

            ExceptionReporter.capture(connection.env, transaction_name: "#{self.class.name}##{action}", extra_context: extra_context) { super }
          end
      end

      module Connection
        private

        def handle_open
          ExceptionReporter.capture(env, transaction_name: self.class.name) { super }
        end
      end
    end
  end
end

ActiveSupport.on_load :action_cable_connection do
  prepend Raven::Integrations::ActionCable::Connection
end

ActiveSupport.on_load :action_cable_channel do
  include Raven::Integrations::ActionCable::Channel::Subscriptions
  prepend Raven::Integrations::ActionCable::Channel::Actions
end

ActiveSupport.on_load :action_cable_channel_test_case do
  class ::ActionCable::Channel::ConnectionStub # rubocop:disable Lint/ConstantDefinitionInBlock, Style/ClassAndModuleChildren
    def env
      @_env ||= ::ActionCable::Connection::TestRequest.create.env # rubocop:disable Rails/SaveBang
    end
  end
end

@st0012
Copy link
Collaborator

st0012 commented Oct 15, 2020

@agrobbin wow this looks great! the 3.x version is now in maintenance mode so we probably won't add ActionCable support to it. but I will add it to the 4.x version's sentry-rails extension (or feel free to submit a PR if you want to 😉)

@st0012 st0012 added the rails label Oct 15, 2020
@agrobbin
Copy link
Contributor

Great to hear that it will be added! I couldn't find time to add test coverage, but hopefully that isn't too hard to do with Action Cable's test helpers.

There are 2 "gotchas" I should mention ...

First off, using the original websocket env does cause Sentry to report the url as /cable (or whatever the mount_path) for all exceptions, which is a little odd. It wasn't worth the effort right now to resolve that (either by clearing out url or doing something else).

Secondly, injecting user_context is not as clean as I'd have hoped. You have to make sure to prepend the module that sets user_context before the above Raven::Integrations::ActionCable::Channel::Actions module, to make sure it's wrapped correctly, in addition to adding separate callbacks for (un)subscribe:

module SentryUserContextActionSupport
  private

  def dispatch_action(*)
    Raven.user_context(id: current_user.id, username: current_user.name, email: current_user.email)

    super
  end
end

module SentryUserContextSubscriptionSupport
  extend ActiveSupport::Concern

  included do
    set_callback :subscribe, :before, :assign_raven_user_context
    set_callback :unsubscribe, :before, :assign_raven_user_context
  end

  private

  def assign_raven_user_context
    Raven.user_context(id: current_user.id, username: current_user.name, email: current_user.email)
  end
end

ActiveSupport.on_load :action_cable_channel do
  # this has to be *before* Sentry's `dispatch_action` integration
  prepend SentryUserContextActionSupport

  require 'raven/integrations/action_cable/channel'

  include Raven::Integrations::ActionCable::Channel::Subscriptions
  prepend Raven::Integrations::ActionCable::Channel::Actions

  include SentryUserContextSubscriptionSupport
end

I didn't want to spend a ton of time right now figuring out a really nice pattern for setting user_context, but it might be worth doing when this gets added officially.

@thrgamon
Copy link

Hey @st0012, we running into the same issue of Actioncable errors not ending up in Sentry and wondering whether to roll the implementation above or wait until sentry 4 drops. Do you have any finger-in-the-air estimate of when that might be?

@st0012
Copy link
Collaborator

st0012 commented Oct 19, 2020

@thrgamon the new SDK may be ready for production by the end of the next month. but the current goal is to make the new SDK's features match the old one's while increasing the stability of it, this feature should need to wait longer than that.

btw, I've implemented the sentry-rails gem and that's where the feature will be added to.

@thrgamon
Copy link

Sure, thanks for the context @st0012!

@github-actions
Copy link

This issue has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you label it Status: Backlog or Status: In Progress, I will leave it alone ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

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