mileszs / wicked_pdf

PDF generator (from HTML) plugin for Ruby on Rails
http://www.mileszs.com/wicked-pdf-plugin
MIT License
3.54k stars 646 forks source link

Error: PDF could not be generated! Command Error: /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/pathname.rb:43:in `chop_basename': undefined method `match?' for /\A(?-mix:\/)?\z/:Regexp (NoMethodError) #892

Open Manidavid opened 4 years ago

Manidavid commented 4 years ago

Am using wicked_pdf gem and it works fine in my local development and production envs, but i deployed it to aws ec2 instance(Ubuntu) and trying to generate the pdf in production it doesn't works.

This is my setup:

Gemfile

gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'

versions

wicked_pdf-2.0.1 wkhtmltopdf-binary-0.12.5.4

config/initializers/wicked_pdf.rb

WickedPdf.config = {
  # Path to the wkhtmltopdf executable: This usually isn't needed if using
  # one of the wkhtmltopdf-binary family of gems.
  # exe_path: '/usr/local/bin/wkhtmltopdf',
  #   or
  # exe_path: Gem.bin_path('wkhtmltopdf-binary', 'wkhtmltopdf')

  # Layout file to be used for all PDFs
  # (but can be overridden in `render :pdf` calls)
  # layout: 'pdf.html',
}

controller/users_controller.rb

  def show
    respond_to do |format|
      format.html
      format.pdf do
        render pdf: "Profile",
        disposition: 'attachment',
        template: "users/show.html.erb"
      end
    end
  end

I Already have html view in /views/users/show.html.erb.

Production error logs

Completed 500 Internal Server Error in 197ms (ActiveRecord: 3.5ms)
F, [2020-03-09T09:44:15.138616 #17187] FATAL -- : [ba8d5272-a497-44c8-badf-872d6421d466]   
F, [2020-03-09T09:44:15.138678 #17187] FATAL -- : [ba8d5272-a497-44c8-badf-872d6421d466] RuntimeError (Failed to execute:
["/data/apps/project-path/vendor/bundle/ruby/2.6.0/bin/wkhtmltopdf", "file:////tmp/wicked_pdf20200309-17187-1cnpjpn.html", "/tmp/wicked_pdf_generated_file20200309-17187-1g27mun.pdf"]
Error: PDF could not be generated!
 Command Error: /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/pathname.rb:43:in `chop_basename': undefined method `match?' for /\A(?-mix:\/)?\z/:Regexp (NoMethodError)
Did you mean?  match
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/pathname.rb:359:in `plus'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/pathname.rb:351:in `+'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/pathname.rb:188:in `parent'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/bundler/shared_helpers.rb:29:in `root'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/bundler.rb:234:in `root'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/bundler.rb:246:in `app_config_path'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/bundler.rb:273:in `settings'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/bundler.rb:84:in `configured_bundle_path'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/bundler.rb:351:in `use_system_gems?'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/bundler.rb:541:in `configure_gem_path'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/bundler.rb:534:in `configure_gem_home_and_path'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/bundler.rb:66:in `configure'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/bundler.rb:134:in `definition'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/bundler.rb:101:in `setup'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/bundler/setup.rb:20:in `<top (required)>'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /home/ubuntu/.rbenv/versions/2.6.0/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
):
F, [2020-03-09T09:44:15.138720 #17187] FATAL -- : [ba8d5272-a497-44c8-badf-872d6421d466]   
F, [2020-03-09T09:44:15.138753 #17187] FATAL -- : [ba8d5272-a497-44c8-badf-872d6421d466] app/controllers/users_controller.rb:27:in `block (2 levels) in show'
[ba8d5272-a497-44c8-badf-872d6421d466] app/controllers/users_controller.rb:24:in `show'
unixmonkey commented 4 years ago

I suspect you are running into an issue similar to the one described in this StackOverflow post, or this issue.

Please check those out and see if maybe they apply to you. I might try directly referencing the named binary, and not the wkhtmltopdf-binary binstub, since that stub invokes Ruby, and it may not run with the same user and permissions that the rest of your app runs as.

Let me know how it goes and what you find out!

Manidavid commented 4 years ago

@unixmonkey, I followed the steps posted on issue https://github.com/mileszs/wicked_pdf/issues/890 and uncompressed the binary from the GEM bin path(vendor/bundle/ruby/2.6.0/gems/wkhtmltopdf-binary-0.12.5.4/bin/) and pointed to exe path.

gunzip wkhtmltopdf-binary-0.12.5.4/bin/wkhtmltopdf_ubuntu_16.04_amd64.gz

config/initializers/wicked_pdf.rb

WickedPdf.config = {
  # Path to the wkhtmltopdf executable: This usually isn't needed if using
  # one of the wkhtmltopdf-binary family of gems.
  # exe_path: '/usr/local/bin/wkhtmltopdf',
  #   or
  # exe_path: Gem.bin_path('wkhtmltopdf-binary', 'wkhtmltopdf')

  exe_path: Rails.root.join('/data/apps/project-path/vendor/bundle/ruby/2.6.0/gems/wkhtmltopdf-binary-0.12.5.4/bin/wkhtmltopdf_ubuntu_16.04_amd64')

  # Layout file to be used for all PDFs
  # (but can be overridden in `render :pdf` calls)
  # layout: 'pdf.html',
}

Here getting the RuntimeError on executing the path

RuntimeError (Failed to execute:
[#<Pathname:/data/apps/project-path/vendor/bundle/ruby/2.6.0/gems/wkhtmltopdf-binary-0.12.5.4/bin/wkhtmltopdf_ubuntu_16.04_amd64>, "file:////tmp/wicked_pdf20200322-6255-14q4v9h.html", "/tmp/wicked_pdf_generated_file20200322-6255-1y2l8gy.pdf"]
Error: no implicit conversion of Pathname into String):
F, [2020-03-22T12:33:05.570275 #6255] FATAL -- : [5c7815dc-0558-45c2-ac0a-b95e99ce2992]   

Also i tried the another stackoverflow post which you mentioned above by changing the exec path to exe_path: '/usr/bin/wkhtmltopdf still not helping to resolve the issues.

unixmonkey commented 4 years ago

Tempfile.new doesn't take a Pathname object, you'll need to convert to a string with to_s, like this:

Rails.root.join('/data/apps/project-path/vendor/bundle/ruby/2.6.0/gems/wkhtmltopdf-binary-0.12.5.4/bin/wkhtmltopdf_ubuntu_16.04_amd64').to_s
Manidavid commented 4 years ago

Now its finally working as expected. so every time do i need to do the same setups on production, still not sure why the ruby wrapper was causing this error though.

Thanks for helping out.

unixmonkey commented 4 years ago

@Manidavid If your Rails app runs as a user with a Ruby that is only available to it, when it shells out to run wkhtmltopdf, in some configurations that might be a different Ruby, or it might not have one at all.

Also, I notice you are using the Ubutntu version. If production is also Ubuntu, there's nothing you need to change, but if it's something else, you may need to pick out a different binary.

My suggestion to you would be to vendor the specific wkhtmltopdf versions you need in your app for both dev and production, or setup your deploy process to specifically copy that file to somewhere it can execute it easily.

Then point my initializer at those files

WickedPdf.config = {
  exe_path: Rails.root.join(
    'bin',
    (Rails.env.development? ? 'wkhtmltopdf-ubuntu' : 'wkhtmltopdf-centos')
  ).to_s
}

Once those files are vendored, you can also remove the wkhtmltopdf-binary gem, which is quite large, since it includes many different versions of the binary for different architectures.