From bfd67952d4645166886ea0c0982d2fd92ade003e Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 17 Jul 2025 14:51:19 +0200 Subject: [PATCH 1/4] feat(js): Update web worker guide with new `webWorkerIntegration` APIs --- .../common/best-practices/web-workers.mdx | 151 +++++++++++++----- .../configuration/integrations/webworker.mdx | 52 ++++++ .../configuration/integrations/javascript.mdx | 1 + 3 files changed, 162 insertions(+), 42 deletions(-) create mode 100644 docs/platforms/javascript/common/configuration/integrations/webworker.mdx diff --git a/docs/platforms/javascript/common/best-practices/web-workers.mdx b/docs/platforms/javascript/common/best-practices/web-workers.mdx index 65e3ff870948c..ad9c01b3f6aff 100644 --- a/docs/platforms/javascript/common/best-practices/web-workers.mdx +++ b/docs/platforms/javascript/common/best-practices/web-workers.mdx @@ -6,18 +6,9 @@ sidebar_order: 9000 supported: - javascript notSupported: - - javascript.angular - javascript.cordova - javascript.electron - - javascript.ember - javascript.gatsby - - javascript.nextjs - - javascript.nuxt - - javascript.react - - javascript.solid - - javascript.solidstart - - javascript.vue - - javascript.wasm - javascript.node - javascript.aws-lambda - javascript.azure-functions @@ -29,28 +20,19 @@ notSupported: - javascript.hono - javascript.koa - javascript.nestjs - - javascript.tanstackstart-react --- -Sentry's Browser SDK supports [Web Workers API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API). To capture unhandled errors from Web Workers: +Sentry's Browser SDK supports the [Web Workers API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API). +You can use the SDK in different ways, though we recommend initializing it in the main thread to capture unhandled errors from workers automatically. -Install `@sentry/browser` using your package manager: +## Recommended Setup -```bash {tabTitle:npm} -npm install @sentry/browser --save -``` - -```bash {tabTitle:yarn} -yarn add @sentry/browser -``` +_Available since_ : 9.40.0 -```bash {tabTitle:pnpm} -pnpm add @sentry/browser -``` - -Then you can use it: +To capture unhandled errors from Web Workers, initialize Sentry in your application code that runs on the main thread +and let the SDK know about the web worker: -```javascript {filename:index.js} +```javascript {filename:index.js} {1-5,9-10} import * as Sentry from "@sentry/browser"; Sentry.init({ @@ -59,34 +41,75 @@ Sentry.init({ const worker = new Worker("worker.js"); +// Add the integration before listening to worker messages +Sentry.addIntegration(Sentry.webWorkerIntegration({ worker })); + +worker.onmessage = (event) => { + // ... +} +``` + +Then, establish communication between the worker and the SDK: + +```javascript {filename:worker.js}{1-4} +import * as Sentry from "@sentry/browser"; + +// Call this before posting any message +Sentry.registerWorker({ self }) + // Errors from `onmessage` callback of `worker.js` -// will be captured. -worker.postMessage("Hello!"); +// will be captured automatically. +self.postMessage("Worker ready!"); +self.onmessage = (event) => { + // ... +} ``` - + -To capture errors or messages manually, such as to use `captureMessage` or `captureException` inside Web Workers, Sentry should be initialized inside each Web Workers' own scope. Only unhandled errors will be captured and sent to Sentry without worker-level initialization. +Ensure that in both, your main thread code as well as the worker, you set up Sentry before you start listening to messages. +The Sentry SDK sends messages from the worker to the main thread, so if you start listening before Sentry is initialized, +the messages will appear in your listeners and you have to handle them manually. -#### Usage Without Worker-Level Initialization +### Multiple Workers + +The `sentryWebWorkerIntegration` supports registering multiple workers. +You can add them directly, when you initialize the integration, or later on. +This is helpful, if you have workers that are initialized at different points in time in your application lifecycle. -```javascript {filename:worker.js} +```javascript {filename:index.js} {1-5, 10-14, 18} import * as Sentry from "@sentry/browser"; -self.onmessage = (message) => { - // This will fail silently. - Sentry.captureMessage("Message received"); +Sentry.init({ + dsn: "___PUBLIC_DSN___", +}); - // This error will be captured. - throw new Error(); -}; +const worker1 = new Worker("worker.js"); +const worker2 = new Worker("worker2.js"); + +// Multiple workers can be added directly: +const webWorkerIntegration = Sentry.webWorkerIntegration({ worker: [worker1, worker2] }); +Sentry.addIntegration(webWorkerIntegration); + +// or later on: +const worker3 = new Worker("worker3.js"); +webWorkerIntegration.addWorker(worker3); ``` -#### Usage With Worker-Level Initialization + + +- Every worker must call `Sentry.registerWorker({ self })` to register itself with the SDK. +- Do not call `Sentry.webWorkerIntegration()` multiple times! This will lead to unexpected behavior. + + + +## Manually Capturing Errors -```javascript {filename:worker.js} +To capture errors or messages manually, via `Sentry.captureMessage` or `Sentry.captureException` inside Web Workers, you can also import the SDK in the worker and initialize it. + +```javascript {filename:worker.js} {1-5,9} import * as Sentry from "@sentry/browser"; Sentry.init({ @@ -102,10 +125,54 @@ self.onmessage = (message) => { }; ``` +Note that initializing the SDK in the worker **completely decouples** it from the SDK running on the main thread. +This means that data like user, tags, traces or scope data set on either side will not be shared with the other side. + +Sometimes, this is the better approach, for instance if you develop a worker that is used in arbitrary applications. +Other times, if the worker is just part of your application, you likely want to use the [SDK from the main thread](#recommended-setup). + + + +If you initialize the SDK in the worker, don't use the `Sentry.webWorkerIntegration` to register the worker. +Likewise, don't use the `Sentry.registerWorker` in the worker. Both methods are only supposed to be used when relying on the SDK [from the main thread](#recommended-setup). + + + ### Integrations -Note, that if you use non-default integrations inside web workers, they may not function as expected. But non-default integrations that are enabled outside of a worker’s scope won’t be affected and will function as expected. This includes Session Replay. +Note, that if you use non-default integrations inside web workers, they may not function as expected. +However, non-default integrations that are enabled on the main thread SDK, won't be affected and will work as expected. +This includes Session Replay. + +## Source Maps + +To ensure that errors from web workers are properly mapped to their original source code, you need to provide source maps to Sentry. +You likely already provide source maps to Sentry for your main application code, but you might need to make adjustments for your worker. + +Importantly, ensure that your bundler also **emits source maps** for the worker bundle(s). -### Source Maps +### Vite +If you use Vite to build your worker, note that the worker build does not take the same plugin as the main code build. +Therefore, you need to add Sentry's Vite plugin to the worker build, in addition to the top-level `plugins` array: -Sentry's source maps integration is supported inside Web Workers, if provided. Learn more about providing your [source maps](/platforms/javascript/sourcemaps/) to Sentry. +```javascript {filename:vite.config.mjs}{1-4,8-9,13,16-17} +const sentryPlugin = sentryVitePlugin({ + org: "sentry-sdks", + project: "javascript", +}); + +export default defineConfig({ + build: { + // This enables source maps for main and worker bundles + sourcemap: "hidden", + }, + + // Vite plugin for main bundle + plugins: [sentryPlugin], + + worker: { + // Vite plugin for worker bundle + plugins: () => [...sentryPlugin], + }, +}); +``` \ No newline at end of file diff --git a/docs/platforms/javascript/common/configuration/integrations/webworker.mdx b/docs/platforms/javascript/common/configuration/integrations/webworker.mdx new file mode 100644 index 0000000000000..01b98e2e00df8 --- /dev/null +++ b/docs/platforms/javascript/common/configuration/integrations/webworker.mdx @@ -0,0 +1,52 @@ +--- +title: WebWorker +description: "Adds source code from inline JavaScript of the current page's HTML." +notSupported: + - javascript.cordova + - javascript.node + - javascript.aws-lambda + - javascript.azure-functions + - javascript.connect + - javascript.express + - javascript.fastify + - javascript.gcp-functions + - javascript.hapi + - javascript.hono + - javascript.koa + - javascript.nestjs + - javascript.deno + - javascript.cloudflare + - javascript.bun +--- + +_Import name: `Sentry.webWorkerIntegration`_ + +This integration, together with `Sentry.registerWorker()`, establishes communication between the browser's main thread and one or multiple [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)s. +It listens to worker messages from the passed workers and forwards them to the main thread. + +Read our Web Worker Guide for more information. + + + +This integration listens to a message, sent from the worker when it calls `Sentry.registerWorker({ self })`. +The purpose is to sync source map information (debugIds) between the main thread and the worker so that worker +errors caught by the main thread SDK are properly mapped to the worker's source code. + + + + +## Options + +### `worker` + +_Type: `Worker | Array`_ + +The web worker(s) to listen to. Every worker must call `Sentry.registerWorker({ self })` to register itself with the SDK. + +## Methods + +### `addWorker(worker: Worker)` + +Adds a worker to the integration, after it was initialized. +This is useful if you have workers that are initialized at later point in your application's lifecycle. +Note that every worker must call `Sentry.registerWorker({ self })` to register itself with the SDK. diff --git a/platform-includes/configuration/integrations/javascript.mdx b/platform-includes/configuration/integrations/javascript.mdx index 02f7f9004fa0a..5141099d4ed84 100644 --- a/platform-includes/configuration/integrations/javascript.mdx +++ b/platform-includes/configuration/integrations/javascript.mdx @@ -29,3 +29,4 @@ | [`statsigIntegration`](./statsig) | | | | | ✓ | | [`supabaseIntegration`](./supabase) | | ✓ | ✓ | | | | [`unleashIntegration`](./unleash) | | | | | ✓ | +| [`webWorkerIntegration`](./webworker) | | ✓ | | | | From 167dd987a78cf62e923354901be8e6a420558c5e Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 17 Jul 2025 17:12:13 +0200 Subject: [PATCH 2/4] fix 404s --- .../javascript/common/best-practices/web-workers.mdx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/platforms/javascript/common/best-practices/web-workers.mdx b/docs/platforms/javascript/common/best-practices/web-workers.mdx index ad9c01b3f6aff..989df30639a9c 100644 --- a/docs/platforms/javascript/common/best-practices/web-workers.mdx +++ b/docs/platforms/javascript/common/best-practices/web-workers.mdx @@ -7,8 +7,6 @@ supported: - javascript notSupported: - javascript.cordova - - javascript.electron - - javascript.gatsby - javascript.node - javascript.aws-lambda - javascript.azure-functions @@ -20,6 +18,9 @@ notSupported: - javascript.hono - javascript.koa - javascript.nestjs + - javascript.deno + - javascript.cloudflare + - javascript.bun --- Sentry's Browser SDK supports the [Web Workers API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API). From bc2f8f9a0e6f4483ef81eaef9b061d60e5041d67 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 22 Jul 2025 17:46:46 +0200 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Alex Krawiec --- .../javascript/common/best-practices/web-workers.mdx | 10 +++++----- .../common/configuration/integrations/webworker.mdx | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/platforms/javascript/common/best-practices/web-workers.mdx b/docs/platforms/javascript/common/best-practices/web-workers.mdx index 989df30639a9c..b3f5e531f7441 100644 --- a/docs/platforms/javascript/common/best-practices/web-workers.mdx +++ b/docs/platforms/javascript/common/best-practices/web-workers.mdx @@ -68,16 +68,16 @@ self.onmessage = (event) => { -Ensure that in both, your main thread code as well as the worker, you set up Sentry before you start listening to messages. +Make sure to initialize Sentry in both the main thread and the worker before either starts listening for messages. The Sentry SDK sends messages from the worker to the main thread, so if you start listening before Sentry is initialized, -the messages will appear in your listeners and you have to handle them manually. +the messages will appear in your listeners and you will have to handle them manually. ### Multiple Workers -The `sentryWebWorkerIntegration` supports registering multiple workers. -You can add them directly, when you initialize the integration, or later on. +The `sentryWebWorkerIntegration` allows you to register multiple workers. +You can add them either when you initialize the integration, or later on. This is helpful, if you have workers that are initialized at different points in time in your application lifecycle. ```javascript {filename:index.js} {1-5, 10-14, 18} @@ -142,7 +142,7 @@ Likewise, don't use the `Sentry.registerWorker` in the worker. Both methods are ### Integrations Note, that if you use non-default integrations inside web workers, they may not function as expected. -However, non-default integrations that are enabled on the main thread SDK, won't be affected and will work as expected. +However, non-default integrations that are enabled on the main thread SDK won't be affected and will work as expected. This includes Session Replay. ## Source Maps diff --git a/docs/platforms/javascript/common/configuration/integrations/webworker.mdx b/docs/platforms/javascript/common/configuration/integrations/webworker.mdx index 01b98e2e00df8..98cec1b5efa68 100644 --- a/docs/platforms/javascript/common/configuration/integrations/webworker.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/webworker.mdx @@ -21,14 +21,14 @@ notSupported: _Import name: `Sentry.webWorkerIntegration`_ -This integration, together with `Sentry.registerWorker()`, establishes communication between the browser's main thread and one or multiple [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)s. +This integration, together with `Sentry.registerWorker()`, establishes communication between the browser's main thread and one or more [WebWorkers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API). It listens to worker messages from the passed workers and forwards them to the main thread. Read our Web Worker Guide for more information. -This integration listens to a message, sent from the worker when it calls `Sentry.registerWorker({ self })`. +This integration listens to a message sent from the worker when it calls `Sentry.registerWorker({ self })`. The purpose is to sync source map information (debugIds) between the main thread and the worker so that worker errors caught by the main thread SDK are properly mapped to the worker's source code. From ccbd7a107180a5e18dfbf223fb4c15f298292df3 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 22 Jul 2025 17:50:10 +0200 Subject: [PATCH 4/4] rewording --- .../common/configuration/integrations/webworker.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/platforms/javascript/common/configuration/integrations/webworker.mdx b/docs/platforms/javascript/common/configuration/integrations/webworker.mdx index 98cec1b5efa68..009f9b4f56b00 100644 --- a/docs/platforms/javascript/common/configuration/integrations/webworker.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/webworker.mdx @@ -1,6 +1,6 @@ --- title: WebWorker -description: "Adds source code from inline JavaScript of the current page's HTML." +description: "Connect Web Workers with the SDK running on the main thread" notSupported: - javascript.cordova - javascript.node @@ -47,6 +47,6 @@ The web worker(s) to listen to. Every worker must call `Sentry.registerWorker({ ### `addWorker(worker: Worker)` -Adds a worker to the integration, after it was initialized. +Adds a worker to the integration, after the integraion was already initialized and added to the SDK. This is useful if you have workers that are initialized at later point in your application's lifecycle. Note that every worker must call `Sentry.registerWorker({ self })` to register itself with the SDK.