Puppeteer DEBUG logs omit page console errors when diagnosing deployment failures
0 reputation · 27 Sept 2021, 06:21 UTC
0 reputation · 27 Sept 2021, 06:21 UTC
When a Puppeteer‑driven deployment fails, developers often turn to the DEBUG logging feature to see the internal Chrome DevTools Protocol messages that Puppeteer emits.
However, DEBUG output does not include console.log statements or JavaScript errors generated by the page itself; those must be captured with separate page.on('console') and page.on('pageerror') listeners. This split creates an unresolved decision about whether DEBUG logs alone are sufficient for diagnosing deployment failures or whether explicit listeners are always required.
Should teams rely on Puppeteer DEBUG output as the primary diagnostic tool for failed deployments, or must they always supplement it with page‑level listeners? How can developers decide consistently when to trust DEBUG logs versus adding explicit event listeners without risking diagnostic gaps?
35275 reputation · 27 Sept 2021, 14:04 UTC
No — DEBUG output alone is not sufficient. Puppeteer's DEBUG=puppeteer:* logging and the page's console output are two separate pipelines, and the DEBUG stream will never contain console.log or JavaScript errors from the page itself. For deployment-failure diagnosis you always need explicit page-level listeners; DEBUG is a supplement, not a substitute.
The DEBUG environment variable enables Puppeteer's own internal logging (via the debug npm package). It shows what Puppeteer is doing — launching Chrome, sending DevTools Protocol commands, waiting for selectors. Page console output travels over the Chrome DevTools Protocol as Runtime.consoleAPICalled and Runtime.exceptionThrown events, which Puppeteer surfaces only through event listeners on the Page object. Nothing bridges those events into the DEBUG log stream.
Attach them immediately after browser.newPage(), before any navigation. This is the most common silent-failure cause: listeners attached after page.goto() miss the console errors emitted during page load — often exactly the errors that explain a failed deployment.
const page = await browser.newPage();
page.on('console', msg => {
console.log(`[page:${msg.type()}]`, msg.text());
});
page.on('pageerror', err => {
console.error('[pageerror]', err.message);
});
page.on('requestfailed', req => {
console.error('[requestfailed]', req.url(), req.failure()?.errorText);
});
await page.goto(deployUrl);
These three cover most deployment diagnostics: application logging, uncaught exceptions, and failed network requests (missing assets, 4xx/5xx API calls). Prefer msg.text() over serializing msg.args() — the args are JSHandles and can hang on unserializable objects.
Use DEBUG=puppeteer:protocol alongside the listeners when you need to isolate a listener bug from a browser problem. The protocol log shows raw CDP traffic, so you can grep for Runtime.consoleAPICalled to confirm Chrome is actually emitting the events. If the events appear in the protocol log but your handler never fires, the bug is in your listener setup (usually timing). If they don't appear, the page genuinely isn't logging.
In CI, console events can be lost if the process exits or the browser closes before async handlers flush. Await the diagnostic step explicitly and close the browser in a finally block. Also note that high-volume console logging can slow headless Chrome; filter by msg.type() (e.g., only error and warning) if noise becomes a problem.
newPage(), reproduce the failing deployment, and confirm errors reach stdout/stderr.await page.evaluate(() => console.error('test')) to prove the listener path works end-to-end.DEBUG=puppeteer:protocol and grep for Runtime.consoleAPICalled to confirm Chrome is emitting events.One caveat: event names and message APIs (msg.type(), msg.text()) have shifted across Puppeteer versions, so check the typings of your installed version rather than assuming. The listener-first pattern itself, though, is stable and should be the default in any deployment-diagnosis harness.
Use comments to ask for clarification. Post a solution as an answer.
5,650 reputation · 27 Sept 2021, 10:52 UTC
To build on the point about separate pipelines, it is important to note that in headless environments (especially CI/CD), console.log calls within the page context are completely isolated from the Node.js process stdout. Without the explicit page.on('console') listener, these messages are effectively discarded.
For teams wanting a unified diagnostic stream, you can manually bridge these pipelines by routing page events into the debug logger. Assuming a standard Node.js environment, you can forward these messages to the system console to keep them alongside your DEBUG=puppeteer:* output:
page.on('console', msg => {
// Use console.debug or a logger to align with DEBUG environment variable
console.debug(`[PAGE-CONSOLE] ${msg.type()}: ${msg.text()}`);
});
When verifying this setup, ensure listeners are attached before page.goto(). If a deployment failure occurs during the initial HTML parsing or early script execution, any listeners attached after navigation will miss the critical startup errors that caused the failure.