October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
browser automation

How to Capture All Console Messages and Errors With Puppeteer

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To capture a page’s browser output, attach Puppeteer listeners immediately after creating the Page and before goto, clicks, or other actions. Use console for JavaScript console calls, pageerror for uncaught exceptions, error for page crashes, requestfailed for transport failures, and response for HTTP status errors such as 404 and 503.

Complete Puppeteer logger

This runnable Node.js example records structured JSON to standard output. It preserves console type, text, source location and serializable arguments, while also recording uncaught exceptions, crashes, failed network requests and HTTP responses with status 400 or higher.

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();

page.on('console', async msg => {
  const values = [];
  for (const arg of msg.args()) {
    try {
      values.push(await arg.jsonValue());
    } catch {
      values.push('[unserializable remote value]');
    }
  }

  console.log(JSON.stringify({
    kind: 'console',
    type: msg.type(),
    text: msg.text(),
    location: msg.location(),
    args: values,
    url: page.url(),
    timestamp: new Date().toISOString()
  }));
});

page.on('pageerror', error => {
  console.error(JSON.stringify({
    kind: 'pageerror',
    message: error instanceof Error ? error.message : String(error),
    stack: error instanceof Error ? error.stack : undefined,
    url: page.url(),
    timestamp: new Date().toISOString()
  }));
});

page.on('error', error => {
  console.error(JSON.stringify({
    kind: 'page-crash',
    message: error.message,
    stack: error.stack,
    url: page.url(),
    timestamp: new Date().toISOString()
  }));
});

page.on('requestfailed', request => {
  const failure = request.failure();
  console.error(JSON.stringify({
    kind: 'requestfailed',
    url: request.url(),
    errorText: failure?.errorText ?? null,
    timestamp: new Date().toISOString()
  }));
});

page.on('response', response => {
  if (response.status() >= 400) {
    console.error(JSON.stringify({
      kind: 'http-error',
      status: response.status(),
      url: response.url(),
      timestamp: new Date().toISOString()
    }));
  }
});

await page.goto('https://example.com');
await browser.close();

The handlers are registered before navigation, so messages emitted during document parsing, script execution and resource loading are not missed. The optional timestamp is generated in Node.js; add a test or page identifier when several pages write to the same log.

What each event captures

console: page console APIs

Puppeteer emits a console event when page JavaScript calls console.log, console.info, console.warn, console.error, console.debug and related APIs. The callback receives a ConsoleMessage.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

msg.text() is convenient for readable output. Use msg.type() to retain severity and msg.location() for the source URL, line and column when available. msg.args() exposes the original remote values, which is important for objects, arrays and multiple arguments:

page.on('console', async msg => {
  console.log(msg.type(), msg.text(), msg.location());
  for (const handle of msg.args()) {
    try {
      console.log(await handle.jsonValue());
    } catch {
      console.log('[unserializable remote value]');
    }
  }
});

Do not assume every argument can be converted to JSON. DOM nodes, cyclic objects, symbols and other remote values can make jsonValue() reject. Catching the conversion error lets the event stream continue.

pageerror: uncaught page exceptions

pageerror is for an exception that escapes page JavaScript without being caught. Record both message and stack; the stack usually identifies the failing script and line. This event is distinct from a deliberate console.error(), which is only a console message.

error: a page crash

The Page-level error event signals that the page crashed. Treat it as a high-severity lifecycle failure rather than an ordinary JavaScript exception. A crash can terminate scripts and prevent later events, so write the record synchronously enough to survive process cleanup and include the current URL.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

requestfailed: no HTTP response was completed

requestfailed covers transport-level failures such as connection errors, DNS problems, aborted requests and timeouts. Call request.failure() for the browser’s error text, but guard the result: the API permits null.

response: HTTP status failures, including 404

A server can return a valid HTTP response with status 404, 500 or 503. That request did not fail at the transport layer, so it does not produce requestfailed. Inspect every response’s status explicitly when you need HTTP error reporting. Filtering at 400 keeps normal traffic out of the log; remove the filter if you need a complete response audit.

Workers and other signals

For pages that rely on dedicated WebWorkers, listen for workercreated and workerdestroyed and record each worker’s URL and lifecycle. Worker activity can explain behavior that is absent from the main page’s console stream.

Attach listeners before anything that can emit

Install listeners directly after newPage(), before goto, clicks, form submissions, evaluate, waits that trigger application work or any custom interaction. Registering after navigation creates a race: early parser errors and startup logs are already gone.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For multi-page tests, apply the same setup whenever a new Page is created. Keep a stable correlation ID in each record so logs from tabs, popups and parallel tests can be separated later:

function addDiagnostics(page, testId) {
  page.on('console', msg => {
    console.log(JSON.stringify({ testId, kind: 'console', type: msg.type(), text: msg.text(), url: page.url() }));
  });
  page.on('pageerror', error => {
    console.error(JSON.stringify({ testId, kind: 'pageerror', message: String(error), stack: error.stack, url: page.url() }));
  });
}

Choosing a logging design

Design Coverage Payload Best use
Minimal forwarding Console only msg.text() Interactive debugging and quick local checks
Structured page logger Console and uncaught exceptions Types, text, arguments, locations and stacks CI diagnostics and searchable logs
Full diagnostic logger Console, exceptions, crashes and network Structured records with URLs, statuses and failure text End-to-end triage and regression investigation

Minimal output is easier to read and produces less volume. Structured output costs more CPU and storage, but it preserves the context needed to diagnose intermittent failures. If many pages run concurrently, write newline-delimited JSON to a stream or logging service rather than retaining records in an ever-growing array.

Making console arguments safe and useful

  • Always catch failures from jsonValue(); one unusual argument should not break the listener.
  • Keep handlers lightweight. Avoid expensive formatting, screenshots or synchronous disk operations inside every event callback.
  • Use msg.text() as a fallback even when argument serialization fails.
  • Include a Node-side timestamp and correlation ID when combining logs from several pages or test workers.
  • Redact credentials, authorization headers and personal data before shipping logs outside the test environment.

Common problems and fixes

“The console listener missed startup messages”

The listener was attached after goto or after an interaction. Move all handlers immediately after newPage(). Also ensure the page is not created by a helper that navigates before returning it.

“A 404 never appears in requestfailed”

This is expected. A 404 is an HTTP response, not a transport failure. Use the response listener and test response.status() >= 400.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“request.failure() is null”

Failure details are optional. Use request.failure()?.errorText ?? null and retain the request URL even when no text is supplied.

“Structured console values cannot be serialized”

Remote objects can contain unsupported or cyclic values. Catch jsonValue() errors and store a marker, while preserving msg.text(). If you need a specific object, have the page emit a JSON-safe representation deliberately.

“The page crashed and later events disappeared”

Handle the Page error event separately and treat it as terminal for that page. Flush your logger, capture the crash record and create a fresh page if the test can safely continue.

“Logs are too noisy for CI”

Keep the full event stream in an artifact, but print a concise summary to the console. Filter known third-party URLs or console types only after confirming that the filtered signals are not part of the failure you are investigating.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“The test hangs after adding logging”

Do not await long-running work from an event handler that the page itself is waiting on. Handlers should enqueue data and return quickly. A bounded queue or asynchronous log writer prevents backpressure from blocking browser events.

Boundaries: what this does not capture

These Page events cover documented page-level console, exception, crash and network signals. They are not a promise to capture every browser diagnostic channel. Browser protocol messages, service-worker diagnostics and application-specific telemetry may require Chrome DevTools Protocol listeners or instrumentation inside the application. Add those channels only when the failure you need is outside the Page event model.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your objective is a clean visual record rather than JavaScript diagnostics, ScreenshotNeo captures a URL through one HTTP request. It accepts cookie and consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before the shot; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients.

See the full parameter reference in the ScreenshotNeo documentation. The same endpoint can return PNG, JPEG, WebP or PDF:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan, and yearly billing gives two months free. Create a free ScreenshotNeo account to get started.

Best Value
The SQL Programming Language: .
  • Used Book in Good Condition

FAQ

Does page.on('console') include browser-level warnings?

It reports console APIs and related page console messages delivered through Puppeteer’s ConsoleMessage. Browser-internal diagnostics outside the Page event model require additional protocol-level instrumentation.

Should HTTP 3xx responses be logged as errors?

Only if your test defines redirects as failures. The example logs statuses 400 and above; change the predicate to match your policy.

Can I use this logger with TypeScript?

Yes. The event names and methods are the same; add types for Puppeteer’s event objects and for your structured log record, then compile the file before running it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why add both pageerror and console?

An uncaught exception and an explicit console.error() represent different failure modes. Keeping both lets CI distinguish a thrown bug from an application-generated diagnostic.

Frequently Asked Questions

Does page.on('console') include browser-level warnings?

It reports console APIs and related page console messages delivered through Puppeteer’s ConsoleMessage. Browser-internal diagnostics outside the Page event model require additional protocol-level instrumentation.

Should HTTP 3xx responses be logged as errors?

Only if your test defines redirects as failures. The example logs statuses 400 and above; change the predicate to match your policy.

Can I use this logger with TypeScript?

Yes. The event names and methods are the same; add types for Puppeteer’s event objects and for your structured log record, then compile the file before running it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.