Skip to content

Errors

The errors subpath captures runtime exceptions and unhandled promise rejections. Bundle target: under 1 kB gzip.

import { installErrors } from '@syntarie/tracking/errors';
const teardown = installErrors();
// Returns a function that removes both listeners.

The single call wires up window.addEventListener('error', ...) and window.addEventListener('unhandledrejection', ...). There is no global state to clean up beyond the two listeners.

Each emit is a TrackingEvent with type: 'error' and these props:

PropTypeNotes
kind'js_error' | 'unhandled_rejection'Which listener fired.
messagestringThe error message.
stackstringTruncated to 50 lines.
sourcestringThe script URL (PII-stripped query string).
linenumberLine number.
columnnumberColumn number.

Errors fingerprint on (message, source, line) and dedup over a 60-second window. A noisy Cannot read properties of undefined (reading 'foo') from the same script line will surface once per minute, not once per requestAnimationFrame.

The source URL has its query string scrubbed before emit. A script URL like https://example.com/app.js?email=alice@example.com&token=abc becomes https://example.com/app.js. The collector additionally runs the server-side PII filter over props.message and props.stack for the same defense-in-depth.

Stack traces from minified bundles are unreadable without sourcemaps. Upload your sourcemaps via POST /sites/:siteId/sourcemaps (legacy bearer scheme) or use the bundled tooling/upload-sourcemaps CLI. The query API resolves frames at read time.

import { installErrors } from '@syntarie/tracking/errors';
const captured: unknown[] = [];
installErrors((event) => captured.push(event));

The customSend parameter is the test seam for unit tests of code that throws. Production callers omit it — the default sender routes through the same pipeline as track().