ARTICLE

Console Error Capture: Debug Without Asking

The widget records the page's last 20 console lines and sends them with each report. What it catches, what it misses, and how to keep secrets out.

Qaid Team
TL;DR

From the moment it starts, the widget records every console.error, console.warn and console.log call, keeps the last 20, and sends them with each report. Uncaught errors are not recorded unless something logs them, and there is no switch to turn capture off. Qaid keeps the lines on Pro projects only.

“The page broke” is a report you can do nothing with. The console usually knows why, so the widget sends the console along.

See what the console said

When the widget starts, it wraps console.error, console.warn and console.log. Each call is recorded, then passed on, so your logs still print as before. It keeps the last 20 lines, dropping the oldest, and sends them with every thumbs report and every screen recording.

There is nothing to turn on. Open an item in the dashboard and the lines are under Console Errors, which counts the errors and warnings and colours each line by its level.

Loading the film…
Pro

Console lines are kept on Pro projects. On Free the widget still sends them, and Qaid drops them when it saves the item. See Free vs Pro.

Know what the log cannot show

On the page In the report
console.error("Save failed for doc", id) Save failed for doc 42: each part turned to text and joined with spaces
console.error(err) with an Error TypeError: x is undefined, with no stack
console.log({ id: 42 }) [object Object]
An uncaught exception or a rejected promise that nothing logs Nothing
A failed network request Nothing
A line logged before the widget started Nothing
The widget’s own messages, like “Screenshot capture failed:” Recorded like any other

With the script tag, the widget starts once the page has been parsed, so a line logged while scripts in <head> run is too early.

Capture thrown errors too

Send uncaught errors through console.error yourself, with the stack as text:

window.addEventListener("error", (event) => {
  console.error(event.error?.stack ?? event.message);
});

window.addEventListener("unhandledrejection", (event) => {
  const reason = event.reason;
  console.error("Unhandled rejection:", reason?.stack ?? String(reason));
});

Your framework may already log its render errors, which the widget then records.

Keep secrets out of the log

Every recorded line leaves the page with the next report. With the hosted endpoint, that means it goes to Qaid.

  1. There is no option to turn capture off, and it includes console.log.
  2. The buffer is not cleared after a report. A second report from the same page view carries the lines from before the first one too.
  3. It runs until destroy().

So don’t log tokens, email addresses or form contents in production:

if (location.hostname === "localhost") {
  console.log("session", session);
}

Flag reports that carry console lines

An escalation rule with Console errors ticked matches any report that has at least one captured line. Warnings and plain logs count, so a page that logs on every load matches every time. Keywords in a rule match the visitor’s message, not the console. See Escalation rules.

Back to all articles