Bu sayfanın Türkçesi de var. Türkçe oku →
Browser errors and source maps
JavaScript errors in your front end are collected with the @errorbird/browser
package. Stack traces from minified code are mapped back to the original code on
the server, using the source maps you upload from your build pipeline:
RangeError: Invalid amount: -5 RangeError: Invalid amount: -5
at n (…/app.4f3c.js:1:34) → at formatPrice (src/checkout.ts:3:11)
at …/app.4f3c.js:1:126 at renderCart (src/checkout.ts:9:30)
at e (…/app.4f3c.js:1:119) at renderCart (src/checkout.ts:9:16)
Grouping uses the mapped text too. The minifier gives functions different names in
every build (n, e, q…) and shifts the columns; if the signature were calculated
from those, every deploy would reopen every existing error as a new Issue.
Installation
npm install @errorbird/browser
At your application's entry point, before any other code:
import { init } from '@errorbird/browser'
init({
key: 'ebrd_pub_…', // publishable key
release: import.meta.env.VITE_RELEASE, // e.g. "[email protected]" or a commit SHA
environment: 'production',
})
That is enough to collect uncaught errors (window.onerror) and unhandled promise
rejections (unhandledrejection). Reporting never breaks the page: network errors
are swallowed, the SDK's own errors are not reported, and calls do nothing during
server-side rendering (when there is no window).
The key. Use only the publishable key; requests must come from an origin on the key's allowed domain list. If the secret key ends up in your bundle, anyone can write on behalf of the project.
Sending errors manually
import { captureException, captureMessage, setTag } from '@errorbird/browser'
try {
await checkout()
} catch (error) {
captureException(error, { tags: { step: 'payment' } })
throw error
}
setTag('tenant', 'acme')
captureMessage('The payment provider responded slowly', 'Warning')
In React, calling captureException(error) in an error boundary's
componentDidCatch is enough.
Options
| Option | Default | Description |
|---|---|---|
key |
— | Publishable key (required) |
endpoint |
https://api.errorbird.com |
API root |
release |
— | Build version; source maps are matched by this name |
environment |
project default | production, staging… |
tags |
— | Tags added to every event (at most 30) |
beforeSend |
— | Changes the event before sending; returning null drops it |
ignoreErrors |
— | Errors whose message matches these strings/regexes are ignored |
captureGlobalErrors |
true |
Whether to install the global listeners |
maxEvents |
50 |
Maximum number of events per page lifetime |
sendQueryString |
false |
Whether to send the ?… part of the page URL |
Noise protection: the same error is sent only once within 60 seconds. The
uninformative Script error. (an error from a script loaded from another origin
without a CORS header; the browser hides the details) and ResizeObserver loop
warnings are skipped by default. The page URL is sent without its query string:
parameters such as ?token=… often carry personal data or secrets.
Uploading source maps
Source maps are uploaded from the build pipeline (CI) with the secret key:
PUT /api/v1/sourcemaps?release=<release>&file=<minified file name>
X-API-KEY: ebrd_secret_…
Content-Type: application/json
<the map itself>
file is the file name as it appears in the stack trace (app.4f3c.js); the path
and the query string are ignored, and a .map suffix is stripped. Uploading again
for the same release and file replaces the old map (workers cache the parsed map, so
the new one takes effect within 30 minutes at the latest; an upload under a new
release name takes effect immediately). Maps are parsed and validated on upload; a
broken map is rejected with 400 invalid_source_map. The limit is 20 MB per file.
An example CI step with Vite:
export RELEASE="web@$(git rev-parse --short HEAD)"
VITE_RELEASE="$RELEASE" npx vite build --sourcemap hidden
for map in dist/assets/*.js.map; do
curl --fail -X PUT \
"https://api.errorbird.com/api/v1/sourcemaps?release=$RELEASE&file=$(basename "$map" .map)" \
-H "X-API-KEY: $ERRORBIRD_SECRET_KEY" \
-H "Content-Type: application/json" \
--data-binary "@$map"
done
# Do not ship the maps: they contain your original source code.
rm dist/assets/*.js.map
--sourcemap hidden produces the maps but does not add the //# sourceMappingURL
comment to the bundle; browsers do not look for them and your source code is not
published. The webpack equivalent is devtool: 'hidden-source-map', and in esbuild
it is --sourcemap=external.
The release name must match exactly. If the release you give the SDK differs
from the release used in the upload, nothing is mapped. The safest approach is to
derive both from the same environment variable (RELEASE above).
How does it work?
- The SDK sends the error to
POST /api/v1/ingest/browser. The endpoint uses the same quota, PII scrubbing and validation as the other ingest endpoints; the only difference is that it allows CORS. - While processing the event, the worker looks at the release tag and the file names in the stack; if it finds a matching map, it maps every frame to the original file, line and column.
- A frame's function name is not taken from the minified name but found in the
map's original source text (
sourcesContent) as the function enclosing the position. For maps without source text, the map'snamesfield is used; in that case the name is less stable across builds. - The signature is calculated from the mapped stack. The minified version is kept
in the event's metadata as
minifiedStackTrace; if a map was uploaded for the wrong release, that is where you find the raw positions.
Both Chrome/Edge (V8: at fn (url:line:column)) and Firefox/Safari
(fn@url:line:column) formats are supported. Lines that cannot be mapped
(at Array.map (<anonymous>), third-party scripts without maps) stay as they are.
Timing. Upload the map before errors arrive; symbolication happens once, when the event is processed, and a map uploaded later does not change past events. A release with no map is remembered as "missing" for one minute, so the short race between a deploy and the upload affects at most a minute of events.
Management
In the dashboard, the Projects page summarizes each project's uploaded maps per release and lets you delete a release's maps. API equivalents:
| Endpoint | Permission |
|---|---|
GET /api/v1/projects/{id}/sourcemaps |
Project member |
DELETE /api/v1/projects/{id}/sourcemaps?release=<release> |
Admin |
Deleting old releases' maps is a good habit; if errors still arrive from that release, they will no longer be mapped once its map is deleted.