Studiosity / grover

A Ruby gem to transform HTML into PDFs, PNGs or JPEGs using Google Puppeteer/Chromium
MIT License
946 stars 107 forks source link

Fail upon JS console errors #263

Open leoc opened 1 month ago

leoc commented 1 month ago

Ok, hope this does not come over as too negative. I love this gem and all it provides. Thanks a lot!

Just want to share my situation of today:

How can I grab this console output and maybe let me know in test, or when debugging in dev?

My ideal situation would be to assert in test, that the rendering of the PDF did not cause any JS errors. And if there are errors, I would like to see them in the test failure output.

Browserless did not connect correctly. I only found out about the JS errors, because I tediously extracted the Rails app from Docker and run it locally. This should not have been necessary.

Did I miss something?

Anyway, heres a dog with pizza.

image

abrom commented 1 month ago

no worries @leoc. There are a few options:

If the error is a request failure, you can enable the raise_on_request_failure option (see the README for details).

If it is an unhandled JS error, puppeteer does support capturing those with an event handler: https://pptr.dev/api/puppeteer.pageevent Although it isn't currently supported, it seems like it would be pretty straight forward to add something to puppeteer to raise an error (with the list of JS errors attached) if any have occurred whilst trying to render the page.

Alternatively, you could have your application "flag" a successful render somewhere in the global scope, then have Grover wait until that holds true. It wouldn't tell you what the error was, but it would timeout the render request thus at least tell you that something went wrong. eg:

... render your page ...
window.renderSuccessful = true;
....

then in grover options add something like:

wait_for_function: 'window.renderSuccessful === true'

Alternatively #2, you could add a window.onerror event handler to capture the errors, where you could assign them to a global object then use the execute_script Grover option to extract them out:

window.pageErrors = [];
window.onerror = (message) => window.pageErrors.push(message);
...

then in grover:

execute_script: "if (window.pageErrors.length > 0) throw `Errors occurred! ${JSON.stringify(window.pageErrors)}`"

or similar.

Note, I haven't tested these, but they should work 😄

Although, if your issue is that your instance wasn't able to connect to Browserless, then that should have raised errors when trying to launch the browser?!

Anyway, hopefully the above will give you something to go on

leoc commented 1 month ago

Wow, thanks for the thorough feedback!

Yeah, I fixed my issue by ejecting the rails app onto my docker host and running it with the debug flags. But until then I spent a good day on trying to get info without doing so, because I had to tackle a lot of environment specifics by pulling it out of the docker setup. And I thought I must have missed something by then. :smile:

Browserless behaved in a weird way and I did not want to spent too much time debugging network issues, so I stopped after a quick try. :)

I will give hooking into onerror a try. I definitely want to be informed about missed renders in production. Currently any error on the rendering page is lost and not logged anywhere.

It cloud be a good addition to the project to have a raise_on_js_error: true. What do you think?

abrom commented 1 month ago

FYI raise_on_js_error feature has been added in v1.1.11 😄

leoc commented 3 weeks ago

Amazing! I planned to get this done after my vacation and now I come back and I can just add this flag: :astonished: Thanks a lot.

By the way you don't have integration tests that would actually test the resulting errors be caught right? Tried to find out what's actually provided by puppeteer. Does this also provide the stacktrace of the JS error?

Got too much going on right now, hope to play around with this soon next week :grin:

abrom commented 1 week ago

Amazing! I planned to get this done after my vacation and now I come back and I can just add this flag: 😲 Thanks a lot.

No probs

By the way you don't have integration tests that would actually test the resulting errors be caught right? Tried to find out what's actually provided by puppeteer. Does this also provide the stacktrace of the JS error?

Yes, there are specs. See https://github.com/Studiosity/grover/pull/264/files#diff-beedb588836752a1b300209c575d884951d3cca658813e67c9d1dad7164babf1R787-R847

No, it doesn't provide the stacktrace, but it would be pretty trivial to add it (here): https://github.com/Studiosity/grover/pull/264/files#diff-0eb7e864fd325efa22797710dcd547c12b55eea103c9a80eedb173a65ff26ef1R206

Got too much going on right now, hope to play around with this soon next week 😁