Capture uncaught JS errors and unhandled promise rejections in the Odoo
web client to Sentry, with optional Performance Monitoring
(BrowserTracing), Session Replay, Browser CPU Profiling, and Console-log
capture tiers behind explicit opt-in toggles.
There are two ways to point the browser SDK at a Sentry project. Use
one:
(a) Recommended — separate browser DSN via the Settings UI. Sentry’s
own guidance is one project per platform: a Python project for backend
errors and a JavaScript-Browser project for client-side errors. Set the
dedicated browser DSN under Settings → General Settings → Sentry
Browser Monitoring → Connection:
| Field |
Example |
Notes |
| Browser DSN |
https://<public_key>@sentry.example.com/<project_id> |
Public DSN of the
JavaScript project.
Safe to embed in client
code per Sentry’s docs. |
| Environment |
production-web |
Tags every browser
event. May differ from
the backend env tag. |
| Release |
asset-bundle hash or deploy SHA |
Tags every browser
event. May differ from
the Odoo Python
release. |
No Odoo restart required — changes take effect on the next page load.
(b) Fallback — shared DSN via ``odoo.conf``. If the Connection
fields above are left blank, the controller reads the same top-level
sentry_* options the OCA server-side sentry module uses on the
18.0 series (the dedicated [sentry] section only exists from 19.0):
[options]
sentry_dsn = https://<public_key>@sentry.example.com/<project_id>
sentry_release = 1.3.2
sentry_environment = production
This path is convenient for single-project deployments that want both
backend Python events and browser JavaScript events going to the same
Sentry project. Editing odoo.conf requires an Odoo restart. A legacy
DSN with a secret (https://key:secret@…) is served to the browser
without the secret part.
The UI value always wins when both are set. Whichever source the DSN
comes from, the controller strips a legacy :<secret> component
before serving it — the browser only ever needs the public key — and the
Settings form refuses a Browser DSN that carries one.
Each tier is independently toggleable:
Loads bundle.min.js (~30KB gzipped). Wires window.onerror and
window.onunhandledrejection. Sends events with the logged-in user’s
id + email as Sentry.setUser(...).
Enables @sentry/replay. Adds ~100KB to every page and records
DOM mutations + console + network activity. Strongly recommend
Healthy-session sample = 0.0 and On-error sample = 1.0 so
recording only kicks in for sessions that already hit an error.
Each user can disable session replay for their own sessions, regardless
of the database-wide Tier 2 setting. The browser SDK still loads (the
bundle URL doesn’t change), but the Replay integration is never
registered for the opted-out user — no DOM observer, no recording.
To enable: open the user’s profile (top-right avatar → My Profile →
Preferences → Privacy) and check Disable Sentry session replay.
The toggle is self-writeable: users can manage it without administrator
help.
What leaves the server per user: events carry the numeric user id plus
the app categories of the user’s groups (e.g. Sales,Accounting) as
the odoo.category tag, cut to Sentry’s 200-character tag limit. No
group names, email or display name are sent; replay masking covers all
text, inputs and media by default.
In the backend (/odoo/*) Odoo’s error service already catches every
window error and unhandled rejection, so the module registers one
error_handlers entry and turns the SDK’s own global handlers and
callback wrappers (GlobalHandlers, BrowserApiErrors) off there.
Each crash is reported once, and OWL component crashes carry two extra
fields:
- tags.owl = true
- extra.component_tree — the OWL component path of the failing
render
Server-side and transport errors (RPCError, including session
expiry, ConnectionLostError, ConnectionAbortedError,
RequestEntityTooLargeError) are not reported from the browser — the
OCA sentry module already reports the server-side ones — they only
leave an odoo.rpc breadcrumb on the next browser event. When Tier 2
replay is on, a server error still uploads the buffered replay, so the
server-side event has a recording to link to through the trace
propagated on the request. Odoo’s standard “Oops!” dialog still shows
as before. No configuration needed. Portal and website pages have no
error service, so the SDK’s global handlers stay on there.
The browser SDK ships vendored inside the module under
sentry_client/static/lib/sentry/<version>/. The default Sentry SDK
source URL points at this in-module path, so the browser loads the SDK
from the same origin as Odoo — no traffic to browser.sentry-cdn.com,
no air-gap workarounds needed.
To bump the vendored version, run the refresh script:
cd sentry_client/
./scripts/refresh-vendor-bundle.sh 10.55.0 # whatever you want
git add static/lib/sentry/10.55.0/
git commit -m "[IMP] sentry_client: bump vendored SDK to 10.55.0"
The script downloads each bundle from browser.sentry-cdn.com,
verifies it against Sentry’s published SHA-384 SRI hash, drops the
LICENSE file, and writes a SHA256SUMS for reviewers. After committing,
update the Sentry SDK version in Settings → General Settings →
Sentry Browser Monitoring to match.
To revert to the public CDN at runtime (e.g. for quick A/B testing),
override Sentry SDK source URL to https://browser.sentry-cdn.com
in the Settings page.
The browser SDK talks to whatever Sentry instance you point the DSN at —
either sentry.io or a self-hosted instance. Feature support depends on
the Sentry server version:
| Feature |
Minimum Sentry
server |
Notes |
| Tier 0 — error
capture |
v9.0+ |
Basic event ingest, supported by every modern Sentry. |
| Tier 1 — performance
/ tracing |
v10.0+ |
The tracing UI shipped in Sentry 10. |
| Tier 2 — session
replay |
v22.10.0+ (Oct 2022)
+ feature flag |
Replay ingest was introduced in self-hosted 22.10. The
feature must also be enabled on the server: set
SENTRY_FEATURES["organizations:session-replay"] = True
(and …-ui, …-recording-scrubbing) in
sentry.conf.py, then restart web +
ingest-replay-recordings. Without the flag, browser
envelopes arrive at /api/<n>/envelope/ but are
silently discarded — no UI surface, no error. |
| Tier 3 — feedback
widget |
v23.6.0+ (Jun 2023) |
The modern programmatic feedback API. Older versions still
work with the legacy Sentry.showReportDialog path,
which this module does not use. |
| Tier 3 — browser
profiling |
v24.0+ (Jan 2024) |
Plus the Document-Policy: js-profiling header (see
above). |
| Tier 3 — console-log
capture |
v25.0+ (Mar 2025) |
Sentry Logs API. Server versions before v25 will ingest
the events as a generic log envelope; the dedicated Logs
UI requires v25+. |
For sentry.io: all features are always available.
For self-hosted: check your tag at /opt/sentry/install/_version.sh
(or docker exec <sentry-web> sentry --version). If a feature you’ve
enabled isn’t supported by your Sentry server, the browser SDK still
sends the envelope but the server discards it — no client-side error.
Once Tier 0 is enabled and a DSN is configured, the next page load
injects the (vendored) Sentry browser SDK and starts capturing errors.
No further user action needed.
To verify the integration:
- Open the browser dev tools console on any Odoo page.
- Run throw new Error("sentry_client smoke test").
- The error appears in your Sentry project within a few seconds, tagged
with your Odoo user.id, release, and environment.
Top-right avatar → My Profile → Preferences → Privacy → Disable Sentry
session replay. Saves to your own user record. The opt-out only
suppresses session replay; basic error capture (Tier 0) still fires.
When the backend OWL stack raises an exception (the usual “Oops!” dialog
you see in the Odoo web client), the resulting Sentry event
automatically carries:
- tags.owl = true
- extra.component_tree — the OWL component path
No configuration needed — the OCA sentry_client module registers an
entry in @web/core/error_handlers at install time. Standard Odoo
error UX is unaffected.
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
feedback.
Do not contact contributors directly about support or help with technical issues.