fix(replay): Improve error messages when compression worker fails to load - #19008

Merged
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working
Feb 10, 2026
Merged

fix(replay): Improve error messages when compression worker fails to load#19008
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working

Conversation

@billyvg

Copy link
Copy Markdown
Member

Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event Event (type=error)").

This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.

Fixes JAVASCRIPT-337J

Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com

@github-actions

github-actionsBot commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser25.53 kB--
@sentry/browser - with treeshaking flags24.05 kB--
@sentry/browser (incl. Tracing)42.36 kB--
@sentry/browser (incl. Tracing, Profiling)47.02 kB--
@sentry/browser (incl. Tracing, Replay)81.14 kB+0.17%+133 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags70.77 kB+0.18%+125 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas)85.84 kB+0.16%+131 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback)98.02 kB+0.12%+117 B 🔺
@sentry/browser (incl. Feedback)42.27 kB--
@sentry/browser (incl. sendFeedback)30.22 kB--
@sentry/browser (incl. FeedbackAsync)35.21 kB--
@sentry/browser (incl. Metrics)26.71 kB--
@sentry/browser (incl. Logs)26.85 kB--
@sentry/browser (incl. Metrics & Logs)27.53 kB--
@sentry/react27.3 kB--
@sentry/react (incl. Tracing)44.68 kB--
@sentry/vue29.98 kB--
@sentry/vue (incl. Tracing)44.2 kB--
@sentry/svelte25.55 kB--
CDN Bundle28.08 kB--
CDN Bundle (incl. Tracing)43.15 kB--
CDN Bundle (incl. Logs, Metrics)28.92 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)43.99 kB--
CDN Bundle (incl. Replay, Logs, Metrics)67.99 kB+0.2%+131 B 🔺
CDN Bundle (incl. Tracing, Replay)80.04 kB+0.17%+130 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)80.91 kB+0.18%+142 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback)85.46 kB+0.16%+132 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)86.36 kB+0.16%+131 B 🔺
CDN Bundle - uncompressed82.12 kB--
CDN Bundle (incl. Tracing) - uncompressed127.83 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed84.95 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed130.66 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed208.62 kB+0.14%+281 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed244.71 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed247.53 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed257.51 kB+0.11%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed260.32 kB+0.11%+281 B 🔺
@sentry/nextjs (client)47.02 kB--
@sentry/sveltekit (client)42.78 kB--
@sentry/node-core52.19 kB--
@sentry/node166.32 kB--
@sentry/node - without tracing93.97 kB--
@sentry/aws-serverless109.48 kB+0.01%+1 B 🔺

View base workflow run

@billyvg
billyvg marked this pull request as ready for review January 27, 2026 18:43
@billyvg
billyvg requested a review from a team as a code ownerJanuary 27, 2026 18:43
new Error(
`Failed to load Replay compression worker: ${error instanceof ErrorEvent && error.message ? error.message : 'Unknown error. This can happen due to CSP policy restrictions, network issues, or the worker script failing to load.'}`,
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test for improved error message regression fix

Low Severity · Bugbot Rules

This PR improves error messages when the compression worker fails to load, but no tests were added to verify the improved error messages are actually produced. The existing test at EventBufferProxy.test.ts only checks that the fallback buffer is used when the worker fails, not that the new descriptive Error objects are correctly constructed and rejected with the expected messages. Per the review rules: "When reviewing a fix PR, check if the PR includes at least one unit, integration or e2e test that tests the regression this PR fixes."

Additional Locations (1)

Fix in CursorFix in Web

Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
'error',
error => {
reject(error);
DEBUG_BUILD && debug.warn('Failed to load Replay compression worker', error);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant debug logging results in duplicate error messages

Low Severity

The new debug.warn calls at lines 36 and 46 are redundant because the caller EventBufferProxy._ensureWorkerIsLoaded() already logs these errors using debug.exception(). Looking at the logger implementation, debug.exception() logs both the message AND the error object to the console. This means when the worker fails to load, the same error appears multiple times in debug output - first as a warning from WorkerHandler, then as error logs from EventBufferProxy. The existing logging in EventBufferProxy provides more useful context (mentioning the fallback behavior), making the new logs unnecessary noise.

Additional Locations (1)

Fix in CursorFix in Web

@github-actions

github-actionsBot commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.
⚠️Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,475-11,850-28%
GET With Sentry1,62119%2,065-22%
GET With Sentry (error only)5,82569%7,827-26%
POST Baseline1,147-1,293-11%
POST With Sentry56049%643-13%
POST With Sentry (error only)1,02189%1,166-12%
MYSQL Baseline3,183-3,564-11%
MYSQL With Sentry38512%528-27%
MYSQL With Sentry (error only)2,57881%3,057-16%

View base workflow run

@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 2d55530 to 5db8e19CompareFebruary 9, 2026 18:30
@github-actions

github-actionsBot commented Feb 9, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

538 passed | ⏭️ 49 skipped | Total: 587 | Pass Rate: 91.65% | Execution Time: 15m 7s

All tests are passing successfully.


Generated by Codecov Action

billyvgand others added 4 commits February 9, 2026 18:00
…load
Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event `Event` (type=error)").
This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.
Fixes JAVASCRIPT-337J
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Andrei <168741329+andreiborza@users.noreply.github.com>
@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 83af4b8 to a442dd3CompareFebruary 9, 2026 23:00

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Comment thread.size-limit.js
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'feedbackIntegration'),
gzip: true,
limit: '98 KB',
limit: '99 KB',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bundle size increase in browser package flagged

Low Severity

Per the review rules: "Large bundle size increases in browser packages. Sometimes they're unavoidable but flag them anyway." The size limit for @sentry/browser (incl. Tracing, Replay, Feedback) was bumped from 98 KB to 99 KB. The increase comes from the new descriptive error message strings added to WorkerHandler. This is likely unavoidable given the goal of improving error messages, but worth noting.

Fix in CursorFix in Web

@andreiborza
andreiborza merged commit bc25ab9 into developFeb 10, 2026
429 of 431 checks passed
@andreiborza
andreiborza deleted the feat-replay-add-error-message-compression-working branch February 10, 2026 10:50
billyvg added a commit that referenced this pull request Jul 20, 2026
…#22377)
tbh I can't find a URL that says safari is more prone to not load a
worker blob if it doesn't have a MIME type, but seems reasonable to add
one.
## Slop
`getWorkerURL()` builds the Replay compression worker from a `Blob` URL,
but the `Blob` was created without a MIME type, so it defaulted to an
empty type. Safari (especially on iOS) validates the MIME type before
executing a `Blob` as a classic `Worker` and silently rejects a non-JS
type — firing a bare `error` event with **no message**, which the SDK
surfaces as:
> Failed to load Replay compression worker: Unknown error. This can
happen due to CSP policy restrictions, network issues, or the worker
script failing to load.
Blink/Gecko are lenient about the blob MIME type, so this particular
failure mode is Safari-specific. Tagging the blob `text/javascript` is
the standard cross-browser fix.
```ts
const workerBlob = new Blob([workerString], { type: 'text/javascript' });
```
This is a handled error — recording already falls back to the
uncompressed buffer — so there is no user-facing behavior change beyond
the worker actually loading on Safari.
## Testing
- New `packages/replay-worker/test/unit/getWorkerURL.test.ts` asserts
the blob is created with the `text/javascript` MIME type.
- `oxlint` + `oxfmt` clean; `replay-worker` suite passes.
## Notes
This is the low-risk half of a split. A separate follow-up PR handles
the cross-browser (Chrome/Edge/Firefox) occurrences of the same captured
error, which come from the worker fetch being aborted during page
navigation/teardown rather than from the MIME type. Follow-up to #19008,
which introduced the descriptive error message but did not address the
load failure itself.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@billyvg@chargome@andreiborza
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(replay): Improve error messages when compression worker fails to load - #19008

Merged
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working
Feb 10, 2026
Merged

fix(replay): Improve error messages when compression worker fails to load#19008
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working

Conversation

@billyvg

Copy link
Copy Markdown
Member

Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event Event (type=error)").

This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.

Fixes JAVASCRIPT-337J

Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com

@github-actions

github-actionsBot commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser25.53 kB--
@sentry/browser - with treeshaking flags24.05 kB--
@sentry/browser (incl. Tracing)42.36 kB--
@sentry/browser (incl. Tracing, Profiling)47.02 kB--
@sentry/browser (incl. Tracing, Replay)81.14 kB+0.17%+133 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags70.77 kB+0.18%+125 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas)85.84 kB+0.16%+131 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback)98.02 kB+0.12%+117 B 🔺
@sentry/browser (incl. Feedback)42.27 kB--
@sentry/browser (incl. sendFeedback)30.22 kB--
@sentry/browser (incl. FeedbackAsync)35.21 kB--
@sentry/browser (incl. Metrics)26.71 kB--
@sentry/browser (incl. Logs)26.85 kB--
@sentry/browser (incl. Metrics & Logs)27.53 kB--
@sentry/react27.3 kB--
@sentry/react (incl. Tracing)44.68 kB--
@sentry/vue29.98 kB--
@sentry/vue (incl. Tracing)44.2 kB--
@sentry/svelte25.55 kB--
CDN Bundle28.08 kB--
CDN Bundle (incl. Tracing)43.15 kB--
CDN Bundle (incl. Logs, Metrics)28.92 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)43.99 kB--
CDN Bundle (incl. Replay, Logs, Metrics)67.99 kB+0.2%+131 B 🔺
CDN Bundle (incl. Tracing, Replay)80.04 kB+0.17%+130 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)80.91 kB+0.18%+142 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback)85.46 kB+0.16%+132 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)86.36 kB+0.16%+131 B 🔺
CDN Bundle - uncompressed82.12 kB--
CDN Bundle (incl. Tracing) - uncompressed127.83 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed84.95 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed130.66 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed208.62 kB+0.14%+281 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed244.71 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed247.53 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed257.51 kB+0.11%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed260.32 kB+0.11%+281 B 🔺
@sentry/nextjs (client)47.02 kB--
@sentry/sveltekit (client)42.78 kB--
@sentry/node-core52.19 kB--
@sentry/node166.32 kB--
@sentry/node - without tracing93.97 kB--
@sentry/aws-serverless109.48 kB+0.01%+1 B 🔺

View base workflow run

@billyvg
billyvg marked this pull request as ready for review January 27, 2026 18:43
@billyvg
billyvg requested a review from a team as a code ownerJanuary 27, 2026 18:43
new Error(
`Failed to load Replay compression worker: ${error instanceof ErrorEvent && error.message ? error.message : 'Unknown error. This can happen due to CSP policy restrictions, network issues, or the worker script failing to load.'}`,
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test for improved error message regression fix

Low Severity · Bugbot Rules

This PR improves error messages when the compression worker fails to load, but no tests were added to verify the improved error messages are actually produced. The existing test at EventBufferProxy.test.ts only checks that the fallback buffer is used when the worker fails, not that the new descriptive Error objects are correctly constructed and rejected with the expected messages. Per the review rules: "When reviewing a fix PR, check if the PR includes at least one unit, integration or e2e test that tests the regression this PR fixes."

Additional Locations (1)

Fix in CursorFix in Web

Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
'error',
error => {
reject(error);
DEBUG_BUILD && debug.warn('Failed to load Replay compression worker', error);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant debug logging results in duplicate error messages

Low Severity

The new debug.warn calls at lines 36 and 46 are redundant because the caller EventBufferProxy._ensureWorkerIsLoaded() already logs these errors using debug.exception(). Looking at the logger implementation, debug.exception() logs both the message AND the error object to the console. This means when the worker fails to load, the same error appears multiple times in debug output - first as a warning from WorkerHandler, then as error logs from EventBufferProxy. The existing logging in EventBufferProxy provides more useful context (mentioning the fallback behavior), making the new logs unnecessary noise.

Additional Locations (1)

Fix in CursorFix in Web

@github-actions

github-actionsBot commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.
⚠️Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,475-11,850-28%
GET With Sentry1,62119%2,065-22%
GET With Sentry (error only)5,82569%7,827-26%
POST Baseline1,147-1,293-11%
POST With Sentry56049%643-13%
POST With Sentry (error only)1,02189%1,166-12%
MYSQL Baseline3,183-3,564-11%
MYSQL With Sentry38512%528-27%
MYSQL With Sentry (error only)2,57881%3,057-16%

View base workflow run

@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 2d55530 to 5db8e19CompareFebruary 9, 2026 18:30
@github-actions

github-actionsBot commented Feb 9, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

538 passed | ⏭️ 49 skipped | Total: 587 | Pass Rate: 91.65% | Execution Time: 15m 7s

All tests are passing successfully.


Generated by Codecov Action

billyvgand others added 4 commits February 9, 2026 18:00
…load
Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event `Event` (type=error)").
This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.
Fixes JAVASCRIPT-337J
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Andrei <168741329+andreiborza@users.noreply.github.com>
@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 83af4b8 to a442dd3CompareFebruary 9, 2026 23:00

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Comment thread.size-limit.js
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'feedbackIntegration'),
gzip: true,
limit: '98 KB',
limit: '99 KB',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bundle size increase in browser package flagged

Low Severity

Per the review rules: "Large bundle size increases in browser packages. Sometimes they're unavoidable but flag them anyway." The size limit for @sentry/browser (incl. Tracing, Replay, Feedback) was bumped from 98 KB to 99 KB. The increase comes from the new descriptive error message strings added to WorkerHandler. This is likely unavoidable given the goal of improving error messages, but worth noting.

Fix in CursorFix in Web

@andreiborza
andreiborza merged commit bc25ab9 into developFeb 10, 2026
429 of 431 checks passed
@andreiborza
andreiborza deleted the feat-replay-add-error-message-compression-working branch February 10, 2026 10:50
billyvg added a commit that referenced this pull request Jul 20, 2026
…#22377)
tbh I can't find a URL that says safari is more prone to not load a
worker blob if it doesn't have a MIME type, but seems reasonable to add
one.
## Slop
`getWorkerURL()` builds the Replay compression worker from a `Blob` URL,
but the `Blob` was created without a MIME type, so it defaulted to an
empty type. Safari (especially on iOS) validates the MIME type before
executing a `Blob` as a classic `Worker` and silently rejects a non-JS
type — firing a bare `error` event with **no message**, which the SDK
surfaces as:
> Failed to load Replay compression worker: Unknown error. This can
happen due to CSP policy restrictions, network issues, or the worker
script failing to load.
Blink/Gecko are lenient about the blob MIME type, so this particular
failure mode is Safari-specific. Tagging the blob `text/javascript` is
the standard cross-browser fix.
```ts
const workerBlob = new Blob([workerString], { type: 'text/javascript' });
```
This is a handled error — recording already falls back to the
uncompressed buffer — so there is no user-facing behavior change beyond
the worker actually loading on Safari.
## Testing
- New `packages/replay-worker/test/unit/getWorkerURL.test.ts` asserts
the blob is created with the `text/javascript` MIME type.
- `oxlint` + `oxfmt` clean; `replay-worker` suite passes.
## Notes
This is the low-risk half of a split. A separate follow-up PR handles
the cross-browser (Chrome/Edge/Firefox) occurrences of the same captured
error, which come from the worker fetch being aborted during page
navigation/teardown rather than from the MIME type. Follow-up to #19008,
which introduced the descriptive error message but did not address the
load failure itself.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@billyvg@chargome@andreiborza
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(replay): Improve error messages when compression worker fails to load - #19008

Merged
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working
Feb 10, 2026
Merged

fix(replay): Improve error messages when compression worker fails to load#19008
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working

Conversation

@billyvg

Copy link
Copy Markdown
Member

Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event Event (type=error)").

This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.

Fixes JAVASCRIPT-337J

Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com

@github-actions

github-actionsBot commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser25.53 kB--
@sentry/browser - with treeshaking flags24.05 kB--
@sentry/browser (incl. Tracing)42.36 kB--
@sentry/browser (incl. Tracing, Profiling)47.02 kB--
@sentry/browser (incl. Tracing, Replay)81.14 kB+0.17%+133 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags70.77 kB+0.18%+125 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas)85.84 kB+0.16%+131 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback)98.02 kB+0.12%+117 B 🔺
@sentry/browser (incl. Feedback)42.27 kB--
@sentry/browser (incl. sendFeedback)30.22 kB--
@sentry/browser (incl. FeedbackAsync)35.21 kB--
@sentry/browser (incl. Metrics)26.71 kB--
@sentry/browser (incl. Logs)26.85 kB--
@sentry/browser (incl. Metrics & Logs)27.53 kB--
@sentry/react27.3 kB--
@sentry/react (incl. Tracing)44.68 kB--
@sentry/vue29.98 kB--
@sentry/vue (incl. Tracing)44.2 kB--
@sentry/svelte25.55 kB--
CDN Bundle28.08 kB--
CDN Bundle (incl. Tracing)43.15 kB--
CDN Bundle (incl. Logs, Metrics)28.92 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)43.99 kB--
CDN Bundle (incl. Replay, Logs, Metrics)67.99 kB+0.2%+131 B 🔺
CDN Bundle (incl. Tracing, Replay)80.04 kB+0.17%+130 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)80.91 kB+0.18%+142 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback)85.46 kB+0.16%+132 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)86.36 kB+0.16%+131 B 🔺
CDN Bundle - uncompressed82.12 kB--
CDN Bundle (incl. Tracing) - uncompressed127.83 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed84.95 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed130.66 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed208.62 kB+0.14%+281 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed244.71 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed247.53 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed257.51 kB+0.11%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed260.32 kB+0.11%+281 B 🔺
@sentry/nextjs (client)47.02 kB--
@sentry/sveltekit (client)42.78 kB--
@sentry/node-core52.19 kB--
@sentry/node166.32 kB--
@sentry/node - without tracing93.97 kB--
@sentry/aws-serverless109.48 kB+0.01%+1 B 🔺

View base workflow run

@billyvg
billyvg marked this pull request as ready for review January 27, 2026 18:43
@billyvg
billyvg requested a review from a team as a code ownerJanuary 27, 2026 18:43
new Error(
`Failed to load Replay compression worker: ${error instanceof ErrorEvent && error.message ? error.message : 'Unknown error. This can happen due to CSP policy restrictions, network issues, or the worker script failing to load.'}`,
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test for improved error message regression fix

Low Severity · Bugbot Rules

This PR improves error messages when the compression worker fails to load, but no tests were added to verify the improved error messages are actually produced. The existing test at EventBufferProxy.test.ts only checks that the fallback buffer is used when the worker fails, not that the new descriptive Error objects are correctly constructed and rejected with the expected messages. Per the review rules: "When reviewing a fix PR, check if the PR includes at least one unit, integration or e2e test that tests the regression this PR fixes."

Additional Locations (1)

Fix in CursorFix in Web

Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
'error',
error => {
reject(error);
DEBUG_BUILD && debug.warn('Failed to load Replay compression worker', error);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant debug logging results in duplicate error messages

Low Severity

The new debug.warn calls at lines 36 and 46 are redundant because the caller EventBufferProxy._ensureWorkerIsLoaded() already logs these errors using debug.exception(). Looking at the logger implementation, debug.exception() logs both the message AND the error object to the console. This means when the worker fails to load, the same error appears multiple times in debug output - first as a warning from WorkerHandler, then as error logs from EventBufferProxy. The existing logging in EventBufferProxy provides more useful context (mentioning the fallback behavior), making the new logs unnecessary noise.

Additional Locations (1)

Fix in CursorFix in Web

@github-actions

github-actionsBot commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.
⚠️Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,475-11,850-28%
GET With Sentry1,62119%2,065-22%
GET With Sentry (error only)5,82569%7,827-26%
POST Baseline1,147-1,293-11%
POST With Sentry56049%643-13%
POST With Sentry (error only)1,02189%1,166-12%
MYSQL Baseline3,183-3,564-11%
MYSQL With Sentry38512%528-27%
MYSQL With Sentry (error only)2,57881%3,057-16%

View base workflow run

@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 2d55530 to 5db8e19CompareFebruary 9, 2026 18:30
@github-actions

github-actionsBot commented Feb 9, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

538 passed | ⏭️ 49 skipped | Total: 587 | Pass Rate: 91.65% | Execution Time: 15m 7s

All tests are passing successfully.


Generated by Codecov Action

billyvgand others added 4 commits February 9, 2026 18:00
…load
Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event `Event` (type=error)").
This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.
Fixes JAVASCRIPT-337J
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Andrei <168741329+andreiborza@users.noreply.github.com>
@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 83af4b8 to a442dd3CompareFebruary 9, 2026 23:00

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Comment thread.size-limit.js
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'feedbackIntegration'),
gzip: true,
limit: '98 KB',
limit: '99 KB',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bundle size increase in browser package flagged

Low Severity

Per the review rules: "Large bundle size increases in browser packages. Sometimes they're unavoidable but flag them anyway." The size limit for @sentry/browser (incl. Tracing, Replay, Feedback) was bumped from 98 KB to 99 KB. The increase comes from the new descriptive error message strings added to WorkerHandler. This is likely unavoidable given the goal of improving error messages, but worth noting.

Fix in CursorFix in Web

@andreiborza
andreiborza merged commit bc25ab9 into developFeb 10, 2026
429 of 431 checks passed
@andreiborza
andreiborza deleted the feat-replay-add-error-message-compression-working branch February 10, 2026 10:50
billyvg added a commit that referenced this pull request Jul 20, 2026
…#22377)
tbh I can't find a URL that says safari is more prone to not load a
worker blob if it doesn't have a MIME type, but seems reasonable to add
one.
## Slop
`getWorkerURL()` builds the Replay compression worker from a `Blob` URL,
but the `Blob` was created without a MIME type, so it defaulted to an
empty type. Safari (especially on iOS) validates the MIME type before
executing a `Blob` as a classic `Worker` and silently rejects a non-JS
type — firing a bare `error` event with **no message**, which the SDK
surfaces as:
> Failed to load Replay compression worker: Unknown error. This can
happen due to CSP policy restrictions, network issues, or the worker
script failing to load.
Blink/Gecko are lenient about the blob MIME type, so this particular
failure mode is Safari-specific. Tagging the blob `text/javascript` is
the standard cross-browser fix.
```ts
const workerBlob = new Blob([workerString], { type: 'text/javascript' });
```
This is a handled error — recording already falls back to the
uncompressed buffer — so there is no user-facing behavior change beyond
the worker actually loading on Safari.
## Testing
- New `packages/replay-worker/test/unit/getWorkerURL.test.ts` asserts
the blob is created with the `text/javascript` MIME type.
- `oxlint` + `oxfmt` clean; `replay-worker` suite passes.
## Notes
This is the low-risk half of a split. A separate follow-up PR handles
the cross-browser (Chrome/Edge/Firefox) occurrences of the same captured
error, which come from the worker fetch being aborted during page
navigation/teardown rather than from the MIME type. Follow-up to #19008,
which introduced the descriptive error message but did not address the
load failure itself.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@billyvg@chargome@andreiborza
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(replay): Improve error messages when compression worker fails to load - #19008

Merged
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working
Feb 10, 2026
Merged

fix(replay): Improve error messages when compression worker fails to load#19008
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working

Conversation

@billyvg

Copy link
Copy Markdown
Member

Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event Event (type=error)").

This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.

Fixes JAVASCRIPT-337J

Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com

@github-actions

github-actionsBot commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser25.53 kB--
@sentry/browser - with treeshaking flags24.05 kB--
@sentry/browser (incl. Tracing)42.36 kB--
@sentry/browser (incl. Tracing, Profiling)47.02 kB--
@sentry/browser (incl. Tracing, Replay)81.14 kB+0.17%+133 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags70.77 kB+0.18%+125 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas)85.84 kB+0.16%+131 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback)98.02 kB+0.12%+117 B 🔺
@sentry/browser (incl. Feedback)42.27 kB--
@sentry/browser (incl. sendFeedback)30.22 kB--
@sentry/browser (incl. FeedbackAsync)35.21 kB--
@sentry/browser (incl. Metrics)26.71 kB--
@sentry/browser (incl. Logs)26.85 kB--
@sentry/browser (incl. Metrics & Logs)27.53 kB--
@sentry/react27.3 kB--
@sentry/react (incl. Tracing)44.68 kB--
@sentry/vue29.98 kB--
@sentry/vue (incl. Tracing)44.2 kB--
@sentry/svelte25.55 kB--
CDN Bundle28.08 kB--
CDN Bundle (incl. Tracing)43.15 kB--
CDN Bundle (incl. Logs, Metrics)28.92 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)43.99 kB--
CDN Bundle (incl. Replay, Logs, Metrics)67.99 kB+0.2%+131 B 🔺
CDN Bundle (incl. Tracing, Replay)80.04 kB+0.17%+130 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)80.91 kB+0.18%+142 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback)85.46 kB+0.16%+132 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)86.36 kB+0.16%+131 B 🔺
CDN Bundle - uncompressed82.12 kB--
CDN Bundle (incl. Tracing) - uncompressed127.83 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed84.95 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed130.66 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed208.62 kB+0.14%+281 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed244.71 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed247.53 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed257.51 kB+0.11%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed260.32 kB+0.11%+281 B 🔺
@sentry/nextjs (client)47.02 kB--
@sentry/sveltekit (client)42.78 kB--
@sentry/node-core52.19 kB--
@sentry/node166.32 kB--
@sentry/node - without tracing93.97 kB--
@sentry/aws-serverless109.48 kB+0.01%+1 B 🔺

View base workflow run

@billyvg
billyvg marked this pull request as ready for review January 27, 2026 18:43
@billyvg
billyvg requested a review from a team as a code ownerJanuary 27, 2026 18:43
new Error(
`Failed to load Replay compression worker: ${error instanceof ErrorEvent && error.message ? error.message : 'Unknown error. This can happen due to CSP policy restrictions, network issues, or the worker script failing to load.'}`,
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test for improved error message regression fix

Low Severity · Bugbot Rules

This PR improves error messages when the compression worker fails to load, but no tests were added to verify the improved error messages are actually produced. The existing test at EventBufferProxy.test.ts only checks that the fallback buffer is used when the worker fails, not that the new descriptive Error objects are correctly constructed and rejected with the expected messages. Per the review rules: "When reviewing a fix PR, check if the PR includes at least one unit, integration or e2e test that tests the regression this PR fixes."

Additional Locations (1)

Fix in CursorFix in Web

Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
'error',
error => {
reject(error);
DEBUG_BUILD && debug.warn('Failed to load Replay compression worker', error);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant debug logging results in duplicate error messages

Low Severity

The new debug.warn calls at lines 36 and 46 are redundant because the caller EventBufferProxy._ensureWorkerIsLoaded() already logs these errors using debug.exception(). Looking at the logger implementation, debug.exception() logs both the message AND the error object to the console. This means when the worker fails to load, the same error appears multiple times in debug output - first as a warning from WorkerHandler, then as error logs from EventBufferProxy. The existing logging in EventBufferProxy provides more useful context (mentioning the fallback behavior), making the new logs unnecessary noise.

Additional Locations (1)

Fix in CursorFix in Web

@github-actions

github-actionsBot commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.
⚠️Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,475-11,850-28%
GET With Sentry1,62119%2,065-22%
GET With Sentry (error only)5,82569%7,827-26%
POST Baseline1,147-1,293-11%
POST With Sentry56049%643-13%
POST With Sentry (error only)1,02189%1,166-12%
MYSQL Baseline3,183-3,564-11%
MYSQL With Sentry38512%528-27%
MYSQL With Sentry (error only)2,57881%3,057-16%

View base workflow run

@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 2d55530 to 5db8e19CompareFebruary 9, 2026 18:30
@github-actions

github-actionsBot commented Feb 9, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

538 passed | ⏭️ 49 skipped | Total: 587 | Pass Rate: 91.65% | Execution Time: 15m 7s

All tests are passing successfully.


Generated by Codecov Action

billyvgand others added 4 commits February 9, 2026 18:00
…load
Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event `Event` (type=error)").
This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.
Fixes JAVASCRIPT-337J
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Andrei <168741329+andreiborza@users.noreply.github.com>
@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 83af4b8 to a442dd3CompareFebruary 9, 2026 23:00

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Comment thread.size-limit.js
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'feedbackIntegration'),
gzip: true,
limit: '98 KB',
limit: '99 KB',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bundle size increase in browser package flagged

Low Severity

Per the review rules: "Large bundle size increases in browser packages. Sometimes they're unavoidable but flag them anyway." The size limit for @sentry/browser (incl. Tracing, Replay, Feedback) was bumped from 98 KB to 99 KB. The increase comes from the new descriptive error message strings added to WorkerHandler. This is likely unavoidable given the goal of improving error messages, but worth noting.

Fix in CursorFix in Web

@andreiborza
andreiborza merged commit bc25ab9 into developFeb 10, 2026
429 of 431 checks passed
@andreiborza
andreiborza deleted the feat-replay-add-error-message-compression-working branch February 10, 2026 10:50
billyvg added a commit that referenced this pull request Jul 20, 2026
…#22377)
tbh I can't find a URL that says safari is more prone to not load a
worker blob if it doesn't have a MIME type, but seems reasonable to add
one.
## Slop
`getWorkerURL()` builds the Replay compression worker from a `Blob` URL,
but the `Blob` was created without a MIME type, so it defaulted to an
empty type. Safari (especially on iOS) validates the MIME type before
executing a `Blob` as a classic `Worker` and silently rejects a non-JS
type — firing a bare `error` event with **no message**, which the SDK
surfaces as:
> Failed to load Replay compression worker: Unknown error. This can
happen due to CSP policy restrictions, network issues, or the worker
script failing to load.
Blink/Gecko are lenient about the blob MIME type, so this particular
failure mode is Safari-specific. Tagging the blob `text/javascript` is
the standard cross-browser fix.
```ts
const workerBlob = new Blob([workerString], { type: 'text/javascript' });
```
This is a handled error — recording already falls back to the
uncompressed buffer — so there is no user-facing behavior change beyond
the worker actually loading on Safari.
## Testing
- New `packages/replay-worker/test/unit/getWorkerURL.test.ts` asserts
the blob is created with the `text/javascript` MIME type.
- `oxlint` + `oxfmt` clean; `replay-worker` suite passes.
## Notes
This is the low-risk half of a split. A separate follow-up PR handles
the cross-browser (Chrome/Edge/Firefox) occurrences of the same captured
error, which come from the worker fetch being aborted during page
navigation/teardown rather than from the MIME type. Follow-up to #19008,
which introduced the descriptive error message but did not address the
load failure itself.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@billyvg@chargome@andreiborza
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(replay): Improve error messages when compression worker fails to load - #19008

Merged
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working
Feb 10, 2026
Merged

fix(replay): Improve error messages when compression worker fails to load#19008
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working

Conversation

@billyvg

Copy link
Copy Markdown
Member

Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event Event (type=error)").

This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.

Fixes JAVASCRIPT-337J

Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com

@github-actions

github-actionsBot commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser25.53 kB--
@sentry/browser - with treeshaking flags24.05 kB--
@sentry/browser (incl. Tracing)42.36 kB--
@sentry/browser (incl. Tracing, Profiling)47.02 kB--
@sentry/browser (incl. Tracing, Replay)81.14 kB+0.17%+133 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags70.77 kB+0.18%+125 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas)85.84 kB+0.16%+131 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback)98.02 kB+0.12%+117 B 🔺
@sentry/browser (incl. Feedback)42.27 kB--
@sentry/browser (incl. sendFeedback)30.22 kB--
@sentry/browser (incl. FeedbackAsync)35.21 kB--
@sentry/browser (incl. Metrics)26.71 kB--
@sentry/browser (incl. Logs)26.85 kB--
@sentry/browser (incl. Metrics & Logs)27.53 kB--
@sentry/react27.3 kB--
@sentry/react (incl. Tracing)44.68 kB--
@sentry/vue29.98 kB--
@sentry/vue (incl. Tracing)44.2 kB--
@sentry/svelte25.55 kB--
CDN Bundle28.08 kB--
CDN Bundle (incl. Tracing)43.15 kB--
CDN Bundle (incl. Logs, Metrics)28.92 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)43.99 kB--
CDN Bundle (incl. Replay, Logs, Metrics)67.99 kB+0.2%+131 B 🔺
CDN Bundle (incl. Tracing, Replay)80.04 kB+0.17%+130 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)80.91 kB+0.18%+142 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback)85.46 kB+0.16%+132 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)86.36 kB+0.16%+131 B 🔺
CDN Bundle - uncompressed82.12 kB--
CDN Bundle (incl. Tracing) - uncompressed127.83 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed84.95 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed130.66 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed208.62 kB+0.14%+281 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed244.71 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed247.53 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed257.51 kB+0.11%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed260.32 kB+0.11%+281 B 🔺
@sentry/nextjs (client)47.02 kB--
@sentry/sveltekit (client)42.78 kB--
@sentry/node-core52.19 kB--
@sentry/node166.32 kB--
@sentry/node - without tracing93.97 kB--
@sentry/aws-serverless109.48 kB+0.01%+1 B 🔺

View base workflow run

@billyvg
billyvg marked this pull request as ready for review January 27, 2026 18:43
@billyvg
billyvg requested a review from a team as a code ownerJanuary 27, 2026 18:43
new Error(
`Failed to load Replay compression worker: ${error instanceof ErrorEvent && error.message ? error.message : 'Unknown error. This can happen due to CSP policy restrictions, network issues, or the worker script failing to load.'}`,
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test for improved error message regression fix

Low Severity · Bugbot Rules

This PR improves error messages when the compression worker fails to load, but no tests were added to verify the improved error messages are actually produced. The existing test at EventBufferProxy.test.ts only checks that the fallback buffer is used when the worker fails, not that the new descriptive Error objects are correctly constructed and rejected with the expected messages. Per the review rules: "When reviewing a fix PR, check if the PR includes at least one unit, integration or e2e test that tests the regression this PR fixes."

Additional Locations (1)

Fix in CursorFix in Web

Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
'error',
error => {
reject(error);
DEBUG_BUILD && debug.warn('Failed to load Replay compression worker', error);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant debug logging results in duplicate error messages

Low Severity

The new debug.warn calls at lines 36 and 46 are redundant because the caller EventBufferProxy._ensureWorkerIsLoaded() already logs these errors using debug.exception(). Looking at the logger implementation, debug.exception() logs both the message AND the error object to the console. This means when the worker fails to load, the same error appears multiple times in debug output - first as a warning from WorkerHandler, then as error logs from EventBufferProxy. The existing logging in EventBufferProxy provides more useful context (mentioning the fallback behavior), making the new logs unnecessary noise.

Additional Locations (1)

Fix in CursorFix in Web

@github-actions

github-actionsBot commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.
⚠️Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,475-11,850-28%
GET With Sentry1,62119%2,065-22%
GET With Sentry (error only)5,82569%7,827-26%
POST Baseline1,147-1,293-11%
POST With Sentry56049%643-13%
POST With Sentry (error only)1,02189%1,166-12%
MYSQL Baseline3,183-3,564-11%
MYSQL With Sentry38512%528-27%
MYSQL With Sentry (error only)2,57881%3,057-16%

View base workflow run

@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 2d55530 to 5db8e19CompareFebruary 9, 2026 18:30
@github-actions

github-actionsBot commented Feb 9, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

538 passed | ⏭️ 49 skipped | Total: 587 | Pass Rate: 91.65% | Execution Time: 15m 7s

All tests are passing successfully.


Generated by Codecov Action

billyvgand others added 4 commits February 9, 2026 18:00
…load
Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event `Event` (type=error)").
This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.
Fixes JAVASCRIPT-337J
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Andrei <168741329+andreiborza@users.noreply.github.com>
@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 83af4b8 to a442dd3CompareFebruary 9, 2026 23:00

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Comment thread.size-limit.js
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'feedbackIntegration'),
gzip: true,
limit: '98 KB',
limit: '99 KB',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bundle size increase in browser package flagged

Low Severity

Per the review rules: "Large bundle size increases in browser packages. Sometimes they're unavoidable but flag them anyway." The size limit for @sentry/browser (incl. Tracing, Replay, Feedback) was bumped from 98 KB to 99 KB. The increase comes from the new descriptive error message strings added to WorkerHandler. This is likely unavoidable given the goal of improving error messages, but worth noting.

Fix in CursorFix in Web

@andreiborza
andreiborza merged commit bc25ab9 into developFeb 10, 2026
429 of 431 checks passed
@andreiborza
andreiborza deleted the feat-replay-add-error-message-compression-working branch February 10, 2026 10:50
billyvg added a commit that referenced this pull request Jul 20, 2026
…#22377)
tbh I can't find a URL that says safari is more prone to not load a
worker blob if it doesn't have a MIME type, but seems reasonable to add
one.
## Slop
`getWorkerURL()` builds the Replay compression worker from a `Blob` URL,
but the `Blob` was created without a MIME type, so it defaulted to an
empty type. Safari (especially on iOS) validates the MIME type before
executing a `Blob` as a classic `Worker` and silently rejects a non-JS
type — firing a bare `error` event with **no message**, which the SDK
surfaces as:
> Failed to load Replay compression worker: Unknown error. This can
happen due to CSP policy restrictions, network issues, or the worker
script failing to load.
Blink/Gecko are lenient about the blob MIME type, so this particular
failure mode is Safari-specific. Tagging the blob `text/javascript` is
the standard cross-browser fix.
```ts
const workerBlob = new Blob([workerString], { type: 'text/javascript' });
```
This is a handled error — recording already falls back to the
uncompressed buffer — so there is no user-facing behavior change beyond
the worker actually loading on Safari.
## Testing
- New `packages/replay-worker/test/unit/getWorkerURL.test.ts` asserts
the blob is created with the `text/javascript` MIME type.
- `oxlint` + `oxfmt` clean; `replay-worker` suite passes.
## Notes
This is the low-risk half of a split. A separate follow-up PR handles
the cross-browser (Chrome/Edge/Firefox) occurrences of the same captured
error, which come from the worker fetch being aborted during page
navigation/teardown rather than from the MIME type. Follow-up to #19008,
which introduced the descriptive error message but did not address the
load failure itself.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@billyvg@chargome@andreiborza
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(replay): Improve error messages when compression worker fails to load - #19008

Merged
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working
Feb 10, 2026
Merged

fix(replay): Improve error messages when compression worker fails to load#19008
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working

Conversation

@billyvg

Copy link
Copy Markdown
Member

Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event Event (type=error)").

This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.

Fixes JAVASCRIPT-337J

Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com

@github-actions

github-actionsBot commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser25.53 kB--
@sentry/browser - with treeshaking flags24.05 kB--
@sentry/browser (incl. Tracing)42.36 kB--
@sentry/browser (incl. Tracing, Profiling)47.02 kB--
@sentry/browser (incl. Tracing, Replay)81.14 kB+0.17%+133 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags70.77 kB+0.18%+125 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas)85.84 kB+0.16%+131 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback)98.02 kB+0.12%+117 B 🔺
@sentry/browser (incl. Feedback)42.27 kB--
@sentry/browser (incl. sendFeedback)30.22 kB--
@sentry/browser (incl. FeedbackAsync)35.21 kB--
@sentry/browser (incl. Metrics)26.71 kB--
@sentry/browser (incl. Logs)26.85 kB--
@sentry/browser (incl. Metrics & Logs)27.53 kB--
@sentry/react27.3 kB--
@sentry/react (incl. Tracing)44.68 kB--
@sentry/vue29.98 kB--
@sentry/vue (incl. Tracing)44.2 kB--
@sentry/svelte25.55 kB--
CDN Bundle28.08 kB--
CDN Bundle (incl. Tracing)43.15 kB--
CDN Bundle (incl. Logs, Metrics)28.92 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)43.99 kB--
CDN Bundle (incl. Replay, Logs, Metrics)67.99 kB+0.2%+131 B 🔺
CDN Bundle (incl. Tracing, Replay)80.04 kB+0.17%+130 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)80.91 kB+0.18%+142 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback)85.46 kB+0.16%+132 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)86.36 kB+0.16%+131 B 🔺
CDN Bundle - uncompressed82.12 kB--
CDN Bundle (incl. Tracing) - uncompressed127.83 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed84.95 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed130.66 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed208.62 kB+0.14%+281 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed244.71 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed247.53 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed257.51 kB+0.11%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed260.32 kB+0.11%+281 B 🔺
@sentry/nextjs (client)47.02 kB--
@sentry/sveltekit (client)42.78 kB--
@sentry/node-core52.19 kB--
@sentry/node166.32 kB--
@sentry/node - without tracing93.97 kB--
@sentry/aws-serverless109.48 kB+0.01%+1 B 🔺

View base workflow run

@billyvg
billyvg marked this pull request as ready for review January 27, 2026 18:43
@billyvg
billyvg requested a review from a team as a code ownerJanuary 27, 2026 18:43
new Error(
`Failed to load Replay compression worker: ${error instanceof ErrorEvent && error.message ? error.message : 'Unknown error. This can happen due to CSP policy restrictions, network issues, or the worker script failing to load.'}`,
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test for improved error message regression fix

Low Severity · Bugbot Rules

This PR improves error messages when the compression worker fails to load, but no tests were added to verify the improved error messages are actually produced. The existing test at EventBufferProxy.test.ts only checks that the fallback buffer is used when the worker fails, not that the new descriptive Error objects are correctly constructed and rejected with the expected messages. Per the review rules: "When reviewing a fix PR, check if the PR includes at least one unit, integration or e2e test that tests the regression this PR fixes."

Additional Locations (1)

Fix in CursorFix in Web

Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
'error',
error => {
reject(error);
DEBUG_BUILD && debug.warn('Failed to load Replay compression worker', error);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant debug logging results in duplicate error messages

Low Severity

The new debug.warn calls at lines 36 and 46 are redundant because the caller EventBufferProxy._ensureWorkerIsLoaded() already logs these errors using debug.exception(). Looking at the logger implementation, debug.exception() logs both the message AND the error object to the console. This means when the worker fails to load, the same error appears multiple times in debug output - first as a warning from WorkerHandler, then as error logs from EventBufferProxy. The existing logging in EventBufferProxy provides more useful context (mentioning the fallback behavior), making the new logs unnecessary noise.

Additional Locations (1)

Fix in CursorFix in Web

@github-actions

github-actionsBot commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.
⚠️Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,475-11,850-28%
GET With Sentry1,62119%2,065-22%
GET With Sentry (error only)5,82569%7,827-26%
POST Baseline1,147-1,293-11%
POST With Sentry56049%643-13%
POST With Sentry (error only)1,02189%1,166-12%
MYSQL Baseline3,183-3,564-11%
MYSQL With Sentry38512%528-27%
MYSQL With Sentry (error only)2,57881%3,057-16%

View base workflow run

@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 2d55530 to 5db8e19CompareFebruary 9, 2026 18:30
@github-actions

github-actionsBot commented Feb 9, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

538 passed | ⏭️ 49 skipped | Total: 587 | Pass Rate: 91.65% | Execution Time: 15m 7s

All tests are passing successfully.


Generated by Codecov Action

billyvgand others added 4 commits February 9, 2026 18:00
…load
Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event `Event` (type=error)").
This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.
Fixes JAVASCRIPT-337J
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Andrei <168741329+andreiborza@users.noreply.github.com>
@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 83af4b8 to a442dd3CompareFebruary 9, 2026 23:00

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Comment thread.size-limit.js
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'feedbackIntegration'),
gzip: true,
limit: '98 KB',
limit: '99 KB',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bundle size increase in browser package flagged

Low Severity

Per the review rules: "Large bundle size increases in browser packages. Sometimes they're unavoidable but flag them anyway." The size limit for @sentry/browser (incl. Tracing, Replay, Feedback) was bumped from 98 KB to 99 KB. The increase comes from the new descriptive error message strings added to WorkerHandler. This is likely unavoidable given the goal of improving error messages, but worth noting.

Fix in CursorFix in Web

@andreiborza
andreiborza merged commit bc25ab9 into developFeb 10, 2026
429 of 431 checks passed
@andreiborza
andreiborza deleted the feat-replay-add-error-message-compression-working branch February 10, 2026 10:50
billyvg added a commit that referenced this pull request Jul 20, 2026
…#22377)
tbh I can't find a URL that says safari is more prone to not load a
worker blob if it doesn't have a MIME type, but seems reasonable to add
one.
## Slop
`getWorkerURL()` builds the Replay compression worker from a `Blob` URL,
but the `Blob` was created without a MIME type, so it defaulted to an
empty type. Safari (especially on iOS) validates the MIME type before
executing a `Blob` as a classic `Worker` and silently rejects a non-JS
type — firing a bare `error` event with **no message**, which the SDK
surfaces as:
> Failed to load Replay compression worker: Unknown error. This can
happen due to CSP policy restrictions, network issues, or the worker
script failing to load.
Blink/Gecko are lenient about the blob MIME type, so this particular
failure mode is Safari-specific. Tagging the blob `text/javascript` is
the standard cross-browser fix.
```ts
const workerBlob = new Blob([workerString], { type: 'text/javascript' });
```
This is a handled error — recording already falls back to the
uncompressed buffer — so there is no user-facing behavior change beyond
the worker actually loading on Safari.
## Testing
- New `packages/replay-worker/test/unit/getWorkerURL.test.ts` asserts
the blob is created with the `text/javascript` MIME type.
- `oxlint` + `oxfmt` clean; `replay-worker` suite passes.
## Notes
This is the low-risk half of a split. A separate follow-up PR handles
the cross-browser (Chrome/Edge/Firefox) occurrences of the same captured
error, which come from the worker fetch being aborted during page
navigation/teardown rather than from the MIME type. Follow-up to #19008,
which introduced the descriptive error message but did not address the
load failure itself.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@billyvg@chargome@andreiborza
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(replay): Improve error messages when compression worker fails to load - #19008

Merged
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working
Feb 10, 2026
Merged

fix(replay): Improve error messages when compression worker fails to load#19008
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working

Conversation

@billyvg

Copy link
Copy Markdown
Member

Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event Event (type=error)").

This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.

Fixes JAVASCRIPT-337J

Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com

@github-actions

github-actionsBot commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser25.53 kB--
@sentry/browser - with treeshaking flags24.05 kB--
@sentry/browser (incl. Tracing)42.36 kB--
@sentry/browser (incl. Tracing, Profiling)47.02 kB--
@sentry/browser (incl. Tracing, Replay)81.14 kB+0.17%+133 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags70.77 kB+0.18%+125 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas)85.84 kB+0.16%+131 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback)98.02 kB+0.12%+117 B 🔺
@sentry/browser (incl. Feedback)42.27 kB--
@sentry/browser (incl. sendFeedback)30.22 kB--
@sentry/browser (incl. FeedbackAsync)35.21 kB--
@sentry/browser (incl. Metrics)26.71 kB--
@sentry/browser (incl. Logs)26.85 kB--
@sentry/browser (incl. Metrics & Logs)27.53 kB--
@sentry/react27.3 kB--
@sentry/react (incl. Tracing)44.68 kB--
@sentry/vue29.98 kB--
@sentry/vue (incl. Tracing)44.2 kB--
@sentry/svelte25.55 kB--
CDN Bundle28.08 kB--
CDN Bundle (incl. Tracing)43.15 kB--
CDN Bundle (incl. Logs, Metrics)28.92 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)43.99 kB--
CDN Bundle (incl. Replay, Logs, Metrics)67.99 kB+0.2%+131 B 🔺
CDN Bundle (incl. Tracing, Replay)80.04 kB+0.17%+130 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)80.91 kB+0.18%+142 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback)85.46 kB+0.16%+132 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)86.36 kB+0.16%+131 B 🔺
CDN Bundle - uncompressed82.12 kB--
CDN Bundle (incl. Tracing) - uncompressed127.83 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed84.95 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed130.66 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed208.62 kB+0.14%+281 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed244.71 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed247.53 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed257.51 kB+0.11%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed260.32 kB+0.11%+281 B 🔺
@sentry/nextjs (client)47.02 kB--
@sentry/sveltekit (client)42.78 kB--
@sentry/node-core52.19 kB--
@sentry/node166.32 kB--
@sentry/node - without tracing93.97 kB--
@sentry/aws-serverless109.48 kB+0.01%+1 B 🔺

View base workflow run

@billyvg
billyvg marked this pull request as ready for review January 27, 2026 18:43
@billyvg
billyvg requested a review from a team as a code ownerJanuary 27, 2026 18:43
new Error(
`Failed to load Replay compression worker: ${error instanceof ErrorEvent && error.message ? error.message : 'Unknown error. This can happen due to CSP policy restrictions, network issues, or the worker script failing to load.'}`,
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test for improved error message regression fix

Low Severity · Bugbot Rules

This PR improves error messages when the compression worker fails to load, but no tests were added to verify the improved error messages are actually produced. The existing test at EventBufferProxy.test.ts only checks that the fallback buffer is used when the worker fails, not that the new descriptive Error objects are correctly constructed and rejected with the expected messages. Per the review rules: "When reviewing a fix PR, check if the PR includes at least one unit, integration or e2e test that tests the regression this PR fixes."

Additional Locations (1)

Fix in CursorFix in Web

Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
'error',
error => {
reject(error);
DEBUG_BUILD && debug.warn('Failed to load Replay compression worker', error);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant debug logging results in duplicate error messages

Low Severity

The new debug.warn calls at lines 36 and 46 are redundant because the caller EventBufferProxy._ensureWorkerIsLoaded() already logs these errors using debug.exception(). Looking at the logger implementation, debug.exception() logs both the message AND the error object to the console. This means when the worker fails to load, the same error appears multiple times in debug output - first as a warning from WorkerHandler, then as error logs from EventBufferProxy. The existing logging in EventBufferProxy provides more useful context (mentioning the fallback behavior), making the new logs unnecessary noise.

Additional Locations (1)

Fix in CursorFix in Web

@github-actions

github-actionsBot commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.
⚠️Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,475-11,850-28%
GET With Sentry1,62119%2,065-22%
GET With Sentry (error only)5,82569%7,827-26%
POST Baseline1,147-1,293-11%
POST With Sentry56049%643-13%
POST With Sentry (error only)1,02189%1,166-12%
MYSQL Baseline3,183-3,564-11%
MYSQL With Sentry38512%528-27%
MYSQL With Sentry (error only)2,57881%3,057-16%

View base workflow run

@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 2d55530 to 5db8e19CompareFebruary 9, 2026 18:30
@github-actions

github-actionsBot commented Feb 9, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

538 passed | ⏭️ 49 skipped | Total: 587 | Pass Rate: 91.65% | Execution Time: 15m 7s

All tests are passing successfully.


Generated by Codecov Action

billyvgand others added 4 commits February 9, 2026 18:00
…load
Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event `Event` (type=error)").
This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.
Fixes JAVASCRIPT-337J
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Andrei <168741329+andreiborza@users.noreply.github.com>
@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 83af4b8 to a442dd3CompareFebruary 9, 2026 23:00

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Comment thread.size-limit.js
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'feedbackIntegration'),
gzip: true,
limit: '98 KB',
limit: '99 KB',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bundle size increase in browser package flagged

Low Severity

Per the review rules: "Large bundle size increases in browser packages. Sometimes they're unavoidable but flag them anyway." The size limit for @sentry/browser (incl. Tracing, Replay, Feedback) was bumped from 98 KB to 99 KB. The increase comes from the new descriptive error message strings added to WorkerHandler. This is likely unavoidable given the goal of improving error messages, but worth noting.

Fix in CursorFix in Web

@andreiborza
andreiborza merged commit bc25ab9 into developFeb 10, 2026
429 of 431 checks passed
@andreiborza
andreiborza deleted the feat-replay-add-error-message-compression-working branch February 10, 2026 10:50
billyvg added a commit that referenced this pull request Jul 20, 2026
…#22377)
tbh I can't find a URL that says safari is more prone to not load a
worker blob if it doesn't have a MIME type, but seems reasonable to add
one.
## Slop
`getWorkerURL()` builds the Replay compression worker from a `Blob` URL,
but the `Blob` was created without a MIME type, so it defaulted to an
empty type. Safari (especially on iOS) validates the MIME type before
executing a `Blob` as a classic `Worker` and silently rejects a non-JS
type — firing a bare `error` event with **no message**, which the SDK
surfaces as:
> Failed to load Replay compression worker: Unknown error. This can
happen due to CSP policy restrictions, network issues, or the worker
script failing to load.
Blink/Gecko are lenient about the blob MIME type, so this particular
failure mode is Safari-specific. Tagging the blob `text/javascript` is
the standard cross-browser fix.
```ts
const workerBlob = new Blob([workerString], { type: 'text/javascript' });
```
This is a handled error — recording already falls back to the
uncompressed buffer — so there is no user-facing behavior change beyond
the worker actually loading on Safari.
## Testing
- New `packages/replay-worker/test/unit/getWorkerURL.test.ts` asserts
the blob is created with the `text/javascript` MIME type.
- `oxlint` + `oxfmt` clean; `replay-worker` suite passes.
## Notes
This is the low-risk half of a split. A separate follow-up PR handles
the cross-browser (Chrome/Edge/Firefox) occurrences of the same captured
error, which come from the worker fetch being aborted during page
navigation/teardown rather than from the MIME type. Follow-up to #19008,
which introduced the descriptive error message but did not address the
load failure itself.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@billyvg@chargome@andreiborza
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(replay): Improve error messages when compression worker fails to load - #19008

Merged
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working
Feb 10, 2026
Merged

fix(replay): Improve error messages when compression worker fails to load#19008
andreiborza merged 6 commits into
developfrom
feat-replay-add-error-message-compression-working

Conversation

@billyvg

Copy link
Copy Markdown
Member

Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event Event (type=error)").

This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.

Fixes JAVASCRIPT-337J

Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com

@github-actions

github-actionsBot commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser25.53 kB--
@sentry/browser - with treeshaking flags24.05 kB--
@sentry/browser (incl. Tracing)42.36 kB--
@sentry/browser (incl. Tracing, Profiling)47.02 kB--
@sentry/browser (incl. Tracing, Replay)81.14 kB+0.17%+133 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags70.77 kB+0.18%+125 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas)85.84 kB+0.16%+131 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback)98.02 kB+0.12%+117 B 🔺
@sentry/browser (incl. Feedback)42.27 kB--
@sentry/browser (incl. sendFeedback)30.22 kB--
@sentry/browser (incl. FeedbackAsync)35.21 kB--
@sentry/browser (incl. Metrics)26.71 kB--
@sentry/browser (incl. Logs)26.85 kB--
@sentry/browser (incl. Metrics & Logs)27.53 kB--
@sentry/react27.3 kB--
@sentry/react (incl. Tracing)44.68 kB--
@sentry/vue29.98 kB--
@sentry/vue (incl. Tracing)44.2 kB--
@sentry/svelte25.55 kB--
CDN Bundle28.08 kB--
CDN Bundle (incl. Tracing)43.15 kB--
CDN Bundle (incl. Logs, Metrics)28.92 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)43.99 kB--
CDN Bundle (incl. Replay, Logs, Metrics)67.99 kB+0.2%+131 B 🔺
CDN Bundle (incl. Tracing, Replay)80.04 kB+0.17%+130 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)80.91 kB+0.18%+142 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback)85.46 kB+0.16%+132 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)86.36 kB+0.16%+131 B 🔺
CDN Bundle - uncompressed82.12 kB--
CDN Bundle (incl. Tracing) - uncompressed127.83 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed84.95 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed130.66 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed208.62 kB+0.14%+281 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed244.71 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed247.53 kB+0.12%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed257.51 kB+0.11%+281 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed260.32 kB+0.11%+281 B 🔺
@sentry/nextjs (client)47.02 kB--
@sentry/sveltekit (client)42.78 kB--
@sentry/node-core52.19 kB--
@sentry/node166.32 kB--
@sentry/node - without tracing93.97 kB--
@sentry/aws-serverless109.48 kB+0.01%+1 B 🔺

View base workflow run

@billyvg
billyvg marked this pull request as ready for review January 27, 2026 18:43
@billyvg
billyvg requested a review from a team as a code ownerJanuary 27, 2026 18:43
new Error(
`Failed to load Replay compression worker: ${error instanceof ErrorEvent && error.message ? error.message : 'Unknown error. This can happen due to CSP policy restrictions, network issues, or the worker script failing to load.'}`,
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test for improved error message regression fix

Low Severity · Bugbot Rules

This PR improves error messages when the compression worker fails to load, but no tests were added to verify the improved error messages are actually produced. The existing test at EventBufferProxy.test.ts only checks that the fallback buffer is used when the worker fails, not that the new descriptive Error objects are correctly constructed and rejected with the expected messages. Per the review rules: "When reviewing a fix PR, check if the PR includes at least one unit, integration or e2e test that tests the regression this PR fixes."

Additional Locations (1)

Fix in CursorFix in Web

Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
Comment threadpackages/replay-internal/src/eventBuffer/WorkerHandler.ts Outdated
'error',
error => {
reject(error);
DEBUG_BUILD && debug.warn('Failed to load Replay compression worker', error);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant debug logging results in duplicate error messages

Low Severity

The new debug.warn calls at lines 36 and 46 are redundant because the caller EventBufferProxy._ensureWorkerIsLoaded() already logs these errors using debug.exception(). Looking at the logger implementation, debug.exception() logs both the message AND the error object to the console. This means when the worker fails to load, the same error appears multiple times in debug output - first as a warning from WorkerHandler, then as error logs from EventBufferProxy. The existing logging in EventBufferProxy provides more useful context (mentioning the fallback behavior), making the new logs unnecessary noise.

Additional Locations (1)

Fix in CursorFix in Web

@github-actions

github-actionsBot commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.
⚠️Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,475-11,850-28%
GET With Sentry1,62119%2,065-22%
GET With Sentry (error only)5,82569%7,827-26%
POST Baseline1,147-1,293-11%
POST With Sentry56049%643-13%
POST With Sentry (error only)1,02189%1,166-12%
MYSQL Baseline3,183-3,564-11%
MYSQL With Sentry38512%528-27%
MYSQL With Sentry (error only)2,57881%3,057-16%

View base workflow run

@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 2d55530 to 5db8e19CompareFebruary 9, 2026 18:30
@github-actions

github-actionsBot commented Feb 9, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

538 passed | ⏭️ 49 skipped | Total: 587 | Pass Rate: 91.65% | Execution Time: 15m 7s

All tests are passing successfully.


Generated by Codecov Action

billyvgand others added 4 commits February 9, 2026 18:00
…load
Previously, when the compression worker failed to load (e.g., due to CSP
restrictions, network issues), Sentry captured a generic ErrorEvent with
almost no useful information ("Event: Event `Event` (type=error)").
This change wraps worker errors in descriptive Error objects that explain
what failed and common causes, making debugging significantly easier.
Fixes JAVASCRIPT-337J
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Andrei <168741329+andreiborza@users.noreply.github.com>
@billyvg
billyvgforce-pushed the feat-replay-add-error-message-compression-working branch from 83af4b8 to a442dd3CompareFebruary 9, 2026 23:00

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Comment thread.size-limit.js
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'feedbackIntegration'),
gzip: true,
limit: '98 KB',
limit: '99 KB',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bundle size increase in browser package flagged

Low Severity

Per the review rules: "Large bundle size increases in browser packages. Sometimes they're unavoidable but flag them anyway." The size limit for @sentry/browser (incl. Tracing, Replay, Feedback) was bumped from 98 KB to 99 KB. The increase comes from the new descriptive error message strings added to WorkerHandler. This is likely unavoidable given the goal of improving error messages, but worth noting.

Fix in CursorFix in Web

@andreiborza
andreiborza merged commit bc25ab9 into developFeb 10, 2026
429 of 431 checks passed
@andreiborza
andreiborza deleted the feat-replay-add-error-message-compression-working branch February 10, 2026 10:50
billyvg added a commit that referenced this pull request Jul 20, 2026
…#22377)
tbh I can't find a URL that says safari is more prone to not load a
worker blob if it doesn't have a MIME type, but seems reasonable to add
one.
## Slop
`getWorkerURL()` builds the Replay compression worker from a `Blob` URL,
but the `Blob` was created without a MIME type, so it defaulted to an
empty type. Safari (especially on iOS) validates the MIME type before
executing a `Blob` as a classic `Worker` and silently rejects a non-JS
type — firing a bare `error` event with **no message**, which the SDK
surfaces as:
> Failed to load Replay compression worker: Unknown error. This can
happen due to CSP policy restrictions, network issues, or the worker
script failing to load.
Blink/Gecko are lenient about the blob MIME type, so this particular
failure mode is Safari-specific. Tagging the blob `text/javascript` is
the standard cross-browser fix.
```ts
const workerBlob = new Blob([workerString], { type: 'text/javascript' });
```
This is a handled error — recording already falls back to the
uncompressed buffer — so there is no user-facing behavior change beyond
the worker actually loading on Safari.
## Testing
- New `packages/replay-worker/test/unit/getWorkerURL.test.ts` asserts
the blob is created with the `text/javascript` MIME type.
- `oxlint` + `oxfmt` clean; `replay-worker` suite passes.
## Notes
This is the low-risk half of a split. A separate follow-up PR handles
the cross-browser (Chrome/Edge/Firefox) occurrences of the same captured
error, which come from the worker fetch being aborted during page
navigation/teardown rather than from the MIME type. Follow-up to #19008,
which introduced the descriptive error message but did not address the
load failure itself.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@billyvg@chargome@andreiborza