Helping Organisations get organised!

How errors are logged and counted

A small script on every front-end page listens for error events, including scripts, stylesheets and images that fail to load. It hands them to LH Beacon, which sends them with any other queued payloads when the page is hidden or closed. Every visitor is logged, crawlers and headless browsers included, since a JavaScript error they hit can break how a page is indexed or used.

How reports arrive

LH Beacon is required (Requires Plugins: lh-beacon); without it the script is not loaded. The script is deferred in the page head and queues its report under the key lh-javascript-error-log, and the server listens on lh_beacon_received_lh-javascript-error-log. No nonce is involved, so reports from cached pages are not lost, and the user ID comes from LH Beacon (0 for logged-out visitors). Each error is sent once: the list is emptied as it is sent, so a later hide only reports new errors.

The first 20 errors on a page are kept (lh_js_error_log_max_errors_per_beacon), on the basis that later ones are often knock-on effects. The report is kept within a byte budget, 4096 by default (lh_js_error_log_return_beacon_budget), because LH Beacon refuses a whole request over its own limit. Over budget, stack traces are shortened first and then the latest errors are dropped.

One row per distinct error

An error’s signature is its site, message, source file (without its query string, so a ?ver= change does not split it), line and column. The page URL is not part of it, so the same error on many pages is one error. When a signature recurs, its row’s error_count goes up, last_seen is updated, and the page, user agent, IP, user and stack trace are refreshed to describe the latest occurrence. logged_at stays as when it was first seen.

What is not logged

Errors raised by browser extensions (any source or stack containing -extension://, or Safari’s webkit-masked-url://) are dropped, since they are not our code. The list is filterable with lh_js_error_log_extension_markers.

Triage

  • document error with line 0 is a resource that failed to load, not an exception. A cluster of them at the same moment on one page usually means the navigation was aborted (redirect, back button, offline), so it only matters if the file is actually missing. The MCP abilities’ kind filter separates these (resources) from thrown errors (exceptions).
  • Script error. with no source is a cross-origin script whose details the browser hides. It cannot be diagnosed unless that script is loaded with crossorigin.
  • Rank by error_count and look at last_seen: a high count that is still recurring is the actionable end of the list.

Storage and retention

One network table on the main site ({base_prefix}lh_js_error_log), schema version 7, tracked in the network option lh_js_error_log_db_version. A daily cron removes errors not seen for a month, so an error that keeps recurring keeps its count. Reports are rate limited per IP (lh_js_error_log_rate_limit, lh_js_error_log_rate_window), on top of LH Beacon’s own limit.

If you like this plugin please consider making a donation to further development