Spoar

errors

Uncaught errors and unhandled rejections, with scrubbed breadcrumbs.

import { errors, scrub } from "@spoar/sdk/plugins";
import { createAnalytics } from "@spoar/sdk";
import { errors } from "@spoar/sdk/plugins";

export const analytics = createAnalytics({
  project: "example.com",
  key: "pk_...",
  endpoint: "/_ra",
  release: "1.4.0",
  plugins: [errors()],
});

Options

errors() takes no options.

Sends

One error event per uncaught error or unhandled promise rejection, through captureError:

PropTypeValue
messagestringThe scrubbed message, cut at 255 characters
typestringThe error's name, such as TypeError
stackstringThe scrubbed stack, cut at 2048 characters; left out when the error has none
levelstringerror
breadcrumbsstringUp to 20 lines, oldest first; past 2048 characters in total the oldest are cut

A rejection with a value that is not an Error is recorded as an Error whose message is that value as a string, with no stack.

An error event with neither an error object nor a line number is not sent. That is the Script error. browsers report for a script from another origin without CORS headers, which hides the message and the stack, so it would only group every such error into one issue nobody can fix. Serve those scripts with crossorigin="anonymous" and an Access-Control-Allow-Origin header to see their errors.

Each line reads <Unix milliseconds> <kind> <message>, with the message scrubbed and cut at 200 characters. Only the last 20 are kept.

KindRecorded whenMessage
navigationA pageview happensThe path
clickAny element is clickedThe tag name, such as BUTTON
fetchA fetch resolves with a status outside 200 to 299The status and the URL
eventAny other event is sentThe event name

A fetch that rejects, such as a network error, adds no breadcrumb. The plugin wraps window.fetch to see responses and restores the original on shutdown().

scrub

scrub(text) is the function the plugin runs over every message, stack and breadcrumb. It drops query strings, up to the : before a stack frame's line number, and replaces emails, tokens of 20 or more letters, digits, underscores or dashes, and runs of 6 or more digits with [x]:

import { scrub } from "@spoar/sdk/plugins";

scrub("GET /api/users?token=abc failed for ada@example.com");
// "GET /api/users[x] failed for [x]"

Use it on your own text before passing it to captureError or captureMessage, which do not scrub in the browser.

In reports

The API scrubs messages, stacks and breadcrumbs again before storing them, then groups errors into issues by type, normalised message and top in-app stack frame. The frame's file is compared without its content hash, so a new deploy keeps the same issue, and a function name of 3 characters or fewer counts as minified and is left out. Errors from bots (a bot score of 50 or more) and from localhost are stored but not grouped into issues, so they open no issue and send no alert. Issues are read with GET /v2/projects/:project/issues, or through the admin client, and the issues SQL view lists them. Set release in the client options so issues record the release they first and last appeared in.

On this page