wicked_pdf
wicked_pdf copied to clipboard
SystemStackError with rspec in 1.4.0
Issue description
Hi @unixmonkey
I've hit a new instance of "stack level too deep" even with the new 1.4.0 (also happens in 1.2.2). This time it does not to involve the "remotipart" gem but just the "WickedPDF" gem.
Funny thing is that this exception only happens in rspec tests of endpoints which performs HTML rendering and not PDF. So when requesting the same endpoint in normal (non-testing) mode it works without problems.
It seems like an edge case but never the less it breaks our test suite and we can't be sure our stuff works.
Reverting to "WickedPDF" version 1.1.0 makes the exception go away.
Example of failing endpoint:
def export_data
respond_to do |format|
format.html {
# export data and check errors
return false if common_export === false
render layout: 'msp_export', template: 'msp/export'
}
format.any { head :unsupported_media_type }
end
end
The above "render" command is the line 258 referred to in the backtrace below.
Simplified Rspec code:
it 'should render html with correct data' do
expect(subject).to receive(:render)
.with(hash_including(layout: 'msp_export', template: 'msp/export'))
.and_call_original
get :export_data, params: {
:target => 'computers',
:clients => [16],
:fields => ['client_name', 'name']
}, :format => :html
expect(subject.instance_variable_get(:@data)).to eq([{:name => 'LaptopZ1', :is_online => false, :client_name => client.name}])
end
Exception:
... (this goes on and on)...
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/wicked_pdf-1.2.2/lib/wicked_pdf/pdf_helper.rb:46:in `call'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/wicked_pdf-1.2.2/lib/wicked_pdf/pdf_helper.rb:46:in `render_with_wicked_pdf'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/wicked_pdf-1.2.2/lib/wicked_pdf/pdf_helper.rb:30:in `render'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/wicked_pdf-1.2.2/lib/wicked_pdf/pdf_helper.rb:46:in `call'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/wicked_pdf-1.2.2/lib/wicked_pdf/pdf_helper.rb:46:in `render_with_wicked_pdf'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/wicked_pdf-1.2.2/lib/wicked_pdf/pdf_helper.rb:30:in `render'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/wicked_pdf-1.2.2/lib/wicked_pdf/pdf_helper.rb:46:in `call'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/wicked_pdf-1.2.2/lib/wicked_pdf/pdf_helper.rb:46:in `render_with_wicked_pdf'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/wicked_pdf-1.2.2/lib/wicked_pdf/pdf_helper.rb:30:in `render'
# ./app/controllers/msp/clients_controller.rb:258:in `block (2 levels) in export_data'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionpack-5.1.7/lib/action_controller/metal/mime_responds.rb:201:in `respond_to'
# ./app/controllers/msp/clients_controller.rb:247:in `export_data'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionpack-5.1.7/lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionpack-5.1.7/lib/abstract_controller/base.rb:186:in `process_action'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionpack-5.1.7/lib/action_controller/metal/rendering.rb:30:in `process_action'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionpack-5.1.7/lib/abstract_controller/callbacks.rb:20:in `block in process_action'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/activesupport-5.1.7/lib/active_support/callbacks.rb:131:in `run_callbacks'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionpack-5.1.7/lib/abstract_controller/callbacks.rb:19:in `process_action'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionpack-5.1.7/lib/action_controller/metal/rescue.rb:20:in `process_action'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionpack-5.1.7/lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/activesupport-5.1.7/lib/active_support/notifications.rb:166:in `block in instrument'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/activesupport-5.1.7/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/activesupport-5.1.7/lib/active_support/notifications.rb:166:in `instrument'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionpack-5.1.7/lib/action_controller/metal/instrumentation.rb:30:in `process_action'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionpack-5.1.7/lib/action_controller/metal/params_wrapper.rb:252:in `process_action'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/activerecord-5.1.7/lib/active_record/railties/controller_runtime.rb:22:in `process_action'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionpack-5.1.7/lib/abstract_controller/base.rb:124:in `process'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionview-5.1.7/lib/action_view/rendering.rb:30:in `process'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionpack-5.1.7/lib/action_controller/metal.rb:189:in `dispatch'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionpack-5.1.7/lib/action_controller/test_case.rb:513:in `process'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/rails-controller-testing-1.0.4/lib/rails/controller/testing/template_assertions.rb:61:in `process'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/devise-4.6.2/lib/devise/test/controller_helpers.rb:35:in `block in process'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/devise-4.6.2/lib/devise/test/controller_helpers.rb:102:in `catch'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/devise-4.6.2/lib/devise/test/controller_helpers.rb:102:in `_catch_warden'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/devise-4.6.2/lib/devise/test/controller_helpers.rb:35:in `process'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/actionpack-5.1.7/lib/action_controller/test_case.rb:392:in `get'
# /home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/rails-controller-testing-1.0.4/lib/rails/controller/testing/integration.rb:13:in `block (2 levels) in <module:Integration>'
# ./spec/controllers/msp/clients_controller_spec.rb:429:in `block (3 levels) in <top (required)>'
UPDATE:
Debugging I found that "method(:render).super_method" in "/home/tb/.rvm/gems/ruby-2.6.2@rails51/gems/wicked_pdf-1.2.2/lib/wicked_pdf/pdf_helper.rb:46:in `call'" returns: #<Method: WickedPdf::PdfHelper#render> which is the immediate cause of the loop.
Expected or desired behavior
No exception should be raised.
System specifications
Ruby: ruby 2.6.2p47 (2019-03-13 revision 67232) [x86_64-linux]
Rails: 5.1.7
Rspec:
ci_reporter_rspec (1.0.0)
rspec (>= 2.14, < 4)
rspec (3.8.0)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
rspec-collection_matchers (1.1.3)
rspec-expectations (>= 2.99.0.beta1)
rspec-core (3.8.2)
rspec-support (~> 3.8.0)
rspec-expectations (3.8.4)
rspec-support (~> 3.8.0)
rspec-mocks (3.8.1)
rspec-support (~> 3.8.0)
rspec-rails (3.8.2)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
rspec-support (~> 3.8.0)
rspec-sidekiq (3.0.3)
rspec-core (~> 3.0, >= 3.0.0)
rspec-support (3.8.2)
rspec_junit_formatter (0.4.1)
rspec-core (>= 2, < 4, != 2.12.0)
ci_reporter_rspec
rspec
rspec-collection_matchers
rspec-rails
rspec-sidekiq (>= 2.2.0)
rspec_junit_formatter
wicked_pdf gem version (output of cat Gemfile.lock | grep wicked_pdf
): wicked_pdf (1.4.0)
wkhtmltopdf version (output of wkhtmltopdf --version
): wkhtmltopdf 0.12.5 (with patched qt)
platform/distribution and version (e.g. Windows 10 / Ubuntu 16.04 / Heroku cedar): Ubuntu 16.04 and Linux Mint 18.3
Same problem arise if method render overided in controller. method(:render) return render from controller. And super_method for it return WickedPdf::PdfHelper#render.
...
# ./app/controllers/application_controller.rb:70:in `render'
# /Users/dborisov/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:46:in `call'
# /Users/dborisov/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:46:in `render_with_wicked_pdf'
# /Users/dborisov/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:30:in `render'
# ./app/controllers/application_controller.rb:70:in `render'
# /Users/dborisov/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:46:in `call'
# /Users/dborisov/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:46:in `render_with_wicked_pdf'
# /Users/dborisov/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:30:in `render'
# ./app/controllers/application_controller.rb:70:in `render'
...
Error occur not only in rspec. Requestion controller in normal mode leads to SystemStackError too.
We're also getting this on any version beyond 1.1. I think @hbda is on the right track - it's something to do with overriding and, perhaps, the way Rails5+ has moved from override_method_chain
to Module#prepend
.
With the latest version of rspec-rails
, 4.0.0
, we have the issue
/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:46:in `call'",
"/Users/eproulx/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:46:in `render_with_wicked_pdf'",
"/Users/eproulx/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:30:in `render'",
"/Users/eproulx/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:46:in `call'",
"/Users/eproulx/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:46:in `render_with_wicked_pdf'",
"/Users/eproulx/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:30:in `render'",
"/Users/eproulx/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:46:in `call'",
"/Users/eproulx/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:46:in `render_with_wicked_pdf'",
"/Users/eproulx/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:30:in `render'",
"/Users/eproulx/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:46:in `call'",
"/Users/eproulx/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:46:in `render_with_wicked_pdf'",
"/Users/eproulx/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:30:in `render'",
"/Users/eproulx/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/gems/wicked_pdf-1.4.0/lib/wicked_pdf/pdf_helper.rb:46:in `call'",
We have a spec that does
expect(controller).to receive(:render).with(plain: :calendar).and_call_original