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.
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.
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.
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.
kind filter separates these (resources) from thrown errors (exceptions).crossorigin.error_count and look at last_seen: a high count that is still recurring is the actionable end of the list.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.