I'm getting an error when rendering PDFs with Grover gem in a rails app:
Grover::JavaScript::TimeoutError: Timed out after waiting 30000ms
Couple key points:
- Using Grover gem on rails 7 app
- Fails in multiple areas grover is used, so points to grover issue or rails integration issue
- When setting grover config to debug: true, the problem seems to go away
- Issue on local development server and on Heroku production
- The same exact code will execute properly, rendering the PDF on some requests within a second or two (seemingly pointing to random erroring, race condition, etc.)
- When it hangs/times out, it does so indefinitely, increasing the timeout doesn't help
I've experimented with wait_until and other options on Grover, to no avail.
Mailer calling code...
def send_invoice_to_email(emails, invoice_id)
@invoice = Invoice.find(invoice_id)
@company = @invoice.company
html = ApplicationController.render(
template: '/invoices/pdf',
formats: :html,
layout: 'pdf',
assigns: {
invoice: @invoice,
company: @company
}
)
pdf = Grover.new(
html,
format: 'A4',
wait_until: 'domcontentloaded'
)
attachments[attachment_name(@invoice)] = pdf.to_pdf
subject = "Invoice #%s" % [invoice_id]
mail(to: emails, subject: subject, tag: 'INVOICE_SEND')
end
Here is the failing test trace...
2) InvoiceMailer Send invoice to email names attachment appropriately
Failure/Error: attachments[attachment_name(@invoice)] = pdf.to_pdf
Grover::JavaScript::TimeoutError:
Timed out after waiting 30000ms
# /usr/share/rvm/gems/ruby-3.3.6/gems/grover-1.2.1/lib/grover/processor.rb:93:in `call_js_method'
# /usr/share/rvm/gems/ruby-3.3.6/gems/grover-1.2.1/lib/grover/processor.rb:20:in `convert'
# /usr/share/rvm/gems/ruby-3.3.6/gems/grover-1.2.1/lib/grover.rb:51:in `to_pdf'
# ./app/mailers/invoice_mailer.rb:24:in `send_invoice_to_email'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actionpack-7.2.2/lib/abstract_controller/base.rb:226:in `process_action'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actionpack-7.2.2/lib/abstract_controller/callbacks.rb:261:in `block in process_action'
# /usr/share/rvm/gems/ruby-3.3.6/gems/activesupport-7.2.2/lib/active_support/callbacks.rb:121:in `block in run_callbacks'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actiontext-7.2.2/lib/action_text/rendering.rb:25:in `with_renderer'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actiontext-7.2.2/lib/action_text/engine.rb:71:in `block (4 levels) in <class:Engine>'
# /usr/share/rvm/gems/ruby-3.3.6/gems/activesupport-7.2.2/lib/active_support/callbacks.rb:130:in `instance_exec'
# /usr/share/rvm/gems/ruby-3.3.6/gems/activesupport-7.2.2/lib/active_support/callbacks.rb:130:in `block in run_callbacks'
# /usr/share/rvm/gems/ruby-3.3.6/gems/activesupport-7.2.2/lib/active_support/callbacks.rb:141:in `run_callbacks'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actionpack-7.2.2/lib/abstract_controller/callbacks.rb:260:in `process_action'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actionpack-7.2.2/lib/abstract_controller/base.rb:163:in `process'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actionmailer-7.2.2/lib/action_mailer/rescuable.rb:29:in `block in process'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actionmailer-7.2.2/lib/action_mailer/rescuable.rb:21:in `handle_exceptions'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actionmailer-7.2.2/lib/action_mailer/rescuable.rb:28:in `process'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actionview-7.2.2/lib/action_view/rendering.rb:40:in `process'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actionmailer-7.2.2/lib/action_mailer/base.rb:657:in `block in process'
# /usr/share/rvm/gems/ruby-3.3.6/gems/activesupport-7.2.2/lib/active_support/notifications.rb:210:in `block in instrument'
# /usr/share/rvm/gems/ruby-3.3.6/gems/activesupport-7.2.2/lib/active_support/notifications/instrumenter.rb:58:in `instrument'
# /usr/share/rvm/gems/ruby-3.3.6/gems/activesupport-7.2.2/lib/active_support/notifications.rb:210:in `instrument'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actionmailer-7.2.2/lib/action_mailer/base.rb:656:in `process'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actionmailer-7.2.2/lib/action_mailer/message_delivery.rb:136:in `block in processed_mailer'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actionmailer-7.2.2/lib/action_mailer/message_delivery.rb:135:in `processed_mailer'
# /usr/share/rvm/gems/ruby-3.3.6/gems/actionmailer-7.2.2/lib/action_mailer/message_delivery.rb:32:in `__getobj__'
# ./spec/mailers/invoice_mailer_spec.rb:29:in `block (3 levels) in <top (required)>'
Templates...
PDF HTML Layout
<!doctype html>
<html>
<head>
<title>
<%= content_for?(:title) ? yield(:title) : "PCI APP - PDF" %>
</title>
<meta charset='utf-8' />
<%= stylesheet_link_tag "application_pdf" %>
</head>
<body style="background-color: #fff">
<div id="content">
<%= yield %>
</div>
</body>
</html>
Invoice PDF HTML template
<div id="invoice-pdf">
<div style="padding: 20px; background-color: #fff">
<%= image_tag 'logo_with_text_gray_inc.png', style: "margin-right: 10px; max-width: 300px;" %>
<h1 class="text-muted float-end">Invoice</h1>
</div>
<hr>
<div class="invoice p-3">
<div class="invoice__header">
<div class="invoice__meta-container">
<div class="invoice__date float-end">
<%= render partial: "invoices/invoice_meta", formats: :html %>
</div>
<div class="invoice__remit">
<%= render partial: "invoices/remit_to", formats: :html %>
</div>
<%= render partial: "invoices/invoice_to", formats: :html, locals: {address: @billing_address} %>
</div>
</div>
<div class="invoice__body">
<hr>
<div>
<%= @invoice.notes&.html_safe %>
</div>
<%= render partial: "invoices/invoice_table", formats: :html %>
</div>
<p>
Accepted payment methods: <b>Check, ACH, Wire Transfer, Bitcoin</b>.
</p>
<p>
<b>We appreciate your business!</b>
</p>
</div> <!-- invoice -->
</div> <!-- #invoice-pdf -->
How can I fix the Javascript Timeout error?