trailblazer / cells

View components for Ruby and Rails.
https://trailblazer.to/2.1/docs/cells.html
3.06k stars 235 forks source link

Cells + Airbrake issue - double exceptions raised #459

Open asaletnik opened 6 years ago

asaletnik commented 6 years ago

Hey guys, I'm having some issue with Airbrake and Cells.

Gems used:

airbrake (7.1.0)
airbrake-ruby (2.6.0)
cells (4.1.7)
cells-haml (0.0.10)
cells-rails (0.0.8)

The problem occurs when there is exception raised within a Cell that doesn't implement a standard show method or view (named after the cell). Here's the relevant part of the stacktrace:

cells (4.1.7) lib/cell/view_model.rb:167:in `find_template'
cells (4.1.7) lib/cell/view_model.rb:109:in `render_to_string'
cells (4.1.7) lib/cell/layout.rb:23:in `render_to_string'
cells (4.1.7) lib/cell/view_model.rb:104:in `render'
cells (4.1.7) lib/cell/view_model.rb:98:in `show'
cells (4.1.7) lib/cell/view_model.rb:114:in `render_state'
cells (4.1.7) lib/cell/caching.rb:46:in `render_state'
cells (4.1.7) lib/cell/view_model.rb:92:in `call'
cells-rails (0.0.8) lib/cell/rails.rb:54:in `call'
cells (4.1.7) lib/cell/layout.rb:43:in `call'
cells (4.1.7) lib/cell/view_model.rb:125:in `to_s'
airbrake-ruby (2.6.0) lib/airbrake-ruby/filters/thread_filter.rb:89:in `sanitize_value'
airbrake-ruby (2.6.0) lib/airbrake-ruby/filters/thread_filter.rb:85:in `block in sanitize_value'
airbrake-ruby (2.6.0) lib/airbrake-ruby/filters/thread_filter.rb:85:in `map'
airbrake-ruby (2.6.0) lib/airbrake-ruby/filters/thread_filter.rb:85:in `sanitize_value'
airbrake-ruby (2.6.0) lib/airbrake-ruby/filters/thread_filter.rb:68:in `block in fiber_variables'
airbrake-ruby (2.6.0) lib/airbrake-ruby/filters/thread_filter.rb:66:in `map'
airbrake-ruby (2.6.0) lib/airbrake-ruby/filters/thread_filter.rb:66:in `with_object'
airbrake-ruby (2.6.0) lib/airbrake-ruby/filters/thread_filter.rb:66:in `fiber_variables'
airbrake-ruby (2.6.0) lib/airbrake-ruby/filters/thread_filter.rb:42:in `call'
airbrake-ruby (2.6.0) lib/airbrake-ruby/filter_chain.rb:47:in `block in refine'
airbrake-ruby (2.6.0) lib/airbrake-ruby/filter_chain.rb:45:in `each'
airbrake-ruby (2.6.0) lib/airbrake-ruby/filter_chain.rb:45:in `refine'
airbrake-ruby (2.6.0) lib/airbrake-ruby/notifier.rb:126:in `send_notice'
airbrake-ruby (2.6.0) lib/airbrake-ruby/notifier.rb:50:in `notify'
airbrake (7.1.0) lib/airbrake/rack/middleware.rb:80:in `notify_airbrake'
airbrake (7.1.0) lib/airbrake/rack/middleware.rb:54:in `rescue in call'
airbrake (7.1.0) lib/airbrake/rack/middleware.rb:51:in `call'

As you can see Airbrake is picking up the exception, and it goes all the way down to here: https://github.com/airbrake/airbrake-ruby/blob/master/lib/airbrake-ruby/filters/thread_filter.rb#L89

value passed to sanitize is the Cell that caused the exception, and calling a to_s on it makes a call on that cell here: https://github.com/trailblazer/cells/blob/master/lib/cell/view_model.rb#L125

Now without that show method implemented on the cell, it tries to load the template by the cell name, and as it is also missing I get another Cell::TemplateMissingError exception raised, within the Airbrake methods, which prevents from reporting the original exception.

I have tried adding empty show method to my cell and it fixed the problem.

But is there any way to make the Airbrake and Cells play nicer? I'm not always using the default show action or view...

asaletnik commented 6 years ago

Furthermore, I have just tried another case - if I use the default show action or view, and the exception is raised somewhere inside, Airbrake picks it up and then calls the same cell again when sanitizing, causing that exception to be raised again... Inside its rescue block.

asaletnik commented 6 years ago

I have made a temporary override in the initializer file, and it fixes the issue for me for now, without breaking anything else:

module Cell
  class ViewModel
    def to_s
      if caller[0].match(/airbrake.*sanitize_value/)
        super
      else
        call
      end
    end
  end
end

// Edit - fixes both cases described above.