Browser monitoring is a beta AppSignal Labs feature. The
@appsignal/browser package is published under the beta tag on npm, and its
configuration and API may still change between beta releases. Share feedback
in our Discord community.init() has run, AppSignal for Browser reports uncaught errors on its own. There is nothing to wrap and no handler to register.
It listens for two things on the page’s main window:
- Errors your code throws and never catches, through the
errorevent. - Promises that fail with nothing to handle the failure, through the
unhandledrejectionevent.
What is reported
- Error name and message. The kind of error, for example
TypeError, and the message it came with. - Backtrace. The stack trace, one line per frame. Empty if the browser gives none.
- Action. The route the error happened on. Errors are grouped by this.
- Revision. The
appVersionyou set. Used to filter by version and to find the right sourcemaps. - Tags. Whatever you set with
setTags(). - Breadcrumbs. The last 25 breadcrumbs before the error.
- URL and user agent. The page the error happened on, with query parameters removed as set by your allowlist, and the browser’s user agent.
browser namespace, which keeps them separate from your back-end errors and their notification settings.
How errors are grouped
Errors group by action, which is the route template you declared withsetRouteTemplate(), or the raw path of the page when you declared none.
Declaring a template is what stops an ID-heavy route from fragmenting into one error group per ID:
Reporting errors manually
UsecaptureError() for errors you catch yourself. It goes through the same pipeline as an uncaught error, including breadcrumbs, tags, sampling, and beforeError:
Tags
Tags are string key-values attached to every error reported from that point on. They are what you filter and search errors by in AppSignal:country_code, country, or browser produces attribute distributions, which break your front-end errors down by that value, and any tag can be turned into a link with link templates.
Rate limits
A page stuck in a loop can throw thousands of errors a second. Two limits stop the SDK from becoming the problem it is meant to report:- The same error over and over. An error counts as the same one when it has the same message and the same first line of stack trace. AppSignal reports it at most five times every 10 seconds.
- Too many errors at once. No more than 100 errors are reported every 10 seconds in total. This catches a page throwing many different errors, which the first limit would miss.
errors.sampleRate.
Sourcemaps
A minified bundle produces stack traces full of one-letter names and enormous line numbers. Sourcemaps turn those back into the file names, functions, and line numbers you wrote. TheappVersion you set is sent with each error as its revision, which is how AppSignal knows which sourcemaps go with which build. Without it, stack traces stay minified.
If your sourcemaps are public, sitting next to your JavaScript files, there is nothing more to do. If you would rather not publish them, upload them to the sourcemaps API endpoint using the same revision.
Errors that are not reported
Errors from scripts on another domain. When a script loaded from somewhere else throws, the browser refuses to share the details. All your page sees is the messageScript error., with no stack trace and no line number. There is nothing in that to debug, so the SDK throws these away rather than filling your error list with entries you cannot tell apart. To get the real errors from scripts on a CDN, serve them with an Access-Control-Allow-Origin header and add crossorigin="anonymous" to the script tags.
Errors inside iframes. The SDK only listens on the page’s main window. An iframe has a window of its own, so errors thrown inside one do not reach it, even when the iframe is on your own domain. To monitor an iframe, call init() inside it as well. An iframe from another domain cannot be monitored at all.
Errors before init(). Anything that throws before init() runs is missed. Import your AppSignal setup first, ahead of other libraries and your own code.
Failed promises with no error in them. A promise can fail with any value, not only an Error. If the value looks close enough to an error, AppSignal keeps its name and message, so a cancelled fetch still reports as AbortError. Anything else is written out as text so the detail survives, which means reject({ code: 500 }) arrives readable instead of empty.