---
title: "Collect script errors from visitors' · Agent Wranglers"
url: https://agentwranglers.se/playbook/website/errors-and-outages/browser-error-reports
id: WEB-228
level: Recommended
updated: 2026-10-22
build: a2a6bdfed830
tokens: 1004
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Collect script errors from visitors' browsers

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Errors and outages](https://agentwranglers.se/playbook/website/errors-and-outages.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-22.

- ID: WEB-228
- Level: Recommended
- Chapter: [Errors and outages](https://agentwranglers.se/playbook/website/errors-and-outages.md)
- Rule: Send every uncaught script error and rejected promise from the browser to your own endpoint, and alert when they rise.
- Check: On a test page, throw an error and reject a promise. Both appear in the server log within a minute, with the build and path and no query string.
- How: Listen for `error` and `unhandledrejection` on `window`. Send the message, the file, the line, the page path and the build with `navigator.sendBeacon`. Send no query string, form values or user ID. Cap reports at a few per page view, and put the endpoint behind the [rate limit](https://agentwranglers.se/playbook/application-security/limits-and-business-logic/rate-limits.md). Group reports by message and build, and alert on new ones after a deploy, as in [alert on symptoms](https://agentwranglers.se/playbook/operations/alerts-and-on-call/alert-on-symptoms.md).

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
const MAX_REPORTS = 5;
let sent = 0;
function report(message, source = '', line = 0) {
  if (sent++ >= MAX_REPORTS) return;
  navigator.sendBeacon('/errors', JSON.stringify({ message: String(message).slice(0, 500), source, line, path: location.pathname, build: document.documentElement.dataset.build }));
}
addEventListener('error', e => report(e.message, e.filename, e.lineno));
addEventListener('unhandledrejection', e => report(e.reason?.message ?? e.reason));
```

### Python example

```python
# Flask: log one line per report, no IP address or cookies
@app.post("/errors")
def browser_errors():
    data = request.get_json(force=True, silent=True) or {}
    app.logger.warning("browser_error build=%s path=%s line=%s message=%r",
        str(data.get("build"))[:40], str(data.get("path"))[:200], data.get("line"), str(data.get("message"))[:500])
    return "", 204
```

## Sources

- [HTML Standard (Runtime script errors)](https://html.spec.whatwg.org/multipage/webappapis.html#runtime-script-errors)
- [HTML Standard (Unhandled promise rejections)](https://html.spec.whatwg.org/multipage/webappapis.html#unhandled-promise-rejections)
- [W3C Beacon](https://www.w3.org/TR/beacon/)

## Related rules

- APS-49 [Limit how often anyone can call your APIs](https://agentwranglers.se/playbook/application-security/limits-and-business-logic/rate-limits.md) in Application security
- OPS-18 [Alert on symptoms](https://agentwranglers.se/playbook/operations/alerts-and-on-call/alert-on-symptoms.md) in Operations and observability
- APP-50 [Contain each crash to its panel](https://agentwranglers.se/playbook/app-ui/resilience/error-boundaries.md) in Web app interface
- STK-67 [Use Sentry only for features GlitchTip lacks](https://agentwranglers.se/playbook/stack/operations-tools/sentry.md) in Software choices

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/website/errors-and-outages/browser-error-reports">Agent Wranglers website playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Serve the last good page when the server fails](https://agentwranglers.se/playbook/website/errors-and-outages/serve-stale-on-error.md)
- [Errors and outages](https://agentwranglers.se/playbook/website/errors-and-outages.md)
