Skip to content

fix(replay): Distinguish worker load failures from page-teardown aborts#22378

Draft
billyvg wants to merge 1 commit into
developfrom
bv/fix-replay-worker-unload-error
Draft

fix(replay): Distinguish worker load failures from page-teardown aborts#22378
billyvg wants to merge 1 commit into
developfrom
bv/fix-replay-worker-unload-error

Conversation

@billyvg

@billyvg billyvg commented Jul 17, 2026

Copy link
Copy Markdown
Member

Summary

Follow-up to #22377 (the Safari MIME fix). This addresses the cross-browser occurrences of the same captured error:

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.

The MIME fix only explains the Safari subset. The 90-day browser.name breakdown on the dogfood issue shows the error is cross-engine:

Browser Events Engine
Safari + Mobile Safari 480 WebKit
Chrome Mobile iOS 51 WebKit (iOS)
Chrome 43 Blink
Edge 16 Blink
Firefox / Firefox iOS 2 Gecko / WebKit

Blink/Gecko don't reject the blob MIME type, so those events have a different cause: the worker fetch is aborted when the page navigates away / is backgrounded while the worker is still loading. The breadcrumbs consistently show fetch aborts (status: None) plus TypeError: Load failed (Safari) / can't access dead object (Firefox) right before the failure — the signature of navigation-time teardown.

WorkerHandler.ensureReady()'s error handler now routes through _getWorkerLoadError(), which distinguishes:

  • an ErrorEvent with a message → use it verbatim,
  • a bare event while the document is hidden/unloading → attribute it to teardown,
  • otherwise → keep the existing generic CSP/network message.

This is a handled error (recording already falls back to the uncompressed buffer), so there's no behavior change beyond a more accurate captured message.

Risk

Higher than #22377 — it changes the error message for some genuine load failures that happen while a tab is hidden (they'll now read "page was hidden or unloaded" instead of the CSP/network catch-all). The hidden-document case is overwhelmingly teardown, but flagging for reviewer judgment. If we'd rather keep capturing those unchanged and only relabel navigation aborts, that's a small tweak.

Testing

  • New ensureReady cases in WorkerHandler.test.ts cover the ErrorEvent.message, hidden-document (teardown), and visible-document (generic) branches.
  • oxlint + oxfmt clean; eventBuffer suite (28) passes.

The "Failed to load Replay compression worker: Unknown error" message is
captured across Chrome, Edge and Firefox as well as Safari. On those engines
the blob MIME type is irrelevant — the error comes from the worker fetch being
aborted when the page navigates away or is backgrounded while the worker is
still loading.

`WorkerHandler.ensureReady()` now routes the worker `error` event through a
helper that distinguishes an aborted load (document hidden/unloading) from a
genuine load failure, so the captured message is accurate instead of always
blaming CSP/network.
@github-actions

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 27.75 kB - -
@sentry/browser - with treeshaking flags 26.18 kB - -
@sentry/browser (incl. Tracing) 46.56 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 48.37 kB - -
@sentry/browser (incl. Tracing, Profiling) 51.36 kB - -
@sentry/browser (incl. Tracing, Replay) 85.88 kB +0.07% +53 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 75.51 kB +0.07% +49 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 90.61 kB +0.06% +53 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 103.25 kB +0.05% +49 B 🔺
@sentry/browser (incl. Feedback) 44.93 kB - -
@sentry/browser (incl. sendFeedback) 32.55 kB - -
@sentry/browser (incl. FeedbackAsync) 37.69 kB - -
@sentry/browser (incl. Metrics) 28.83 kB - -
@sentry/browser (incl. Logs) 29.05 kB - -
@sentry/browser (incl. Metrics & Logs) 29.76 kB - -
@sentry/react 29.54 kB - -
@sentry/react (incl. Tracing) 48.84 kB - -
@sentry/vue 33.17 kB - -
@sentry/vue (incl. Tracing) 48.51 kB - -
@sentry/svelte 27.78 kB - -
CDN Bundle 30.14 kB - -
CDN Bundle (incl. Tracing) 48.53 kB - -
CDN Bundle (incl. Logs, Metrics) 31.73 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 49.83 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 71.03 kB +0.08% +54 B 🔺
CDN Bundle (incl. Tracing, Replay) 86.1 kB +0.07% +56 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 87.4 kB +0.07% +56 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 91.89 kB +0.06% +55 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 93.17 kB +0.07% +56 B 🔺
CDN Bundle - uncompressed 89.88 kB - -
CDN Bundle (incl. Tracing) - uncompressed 146.73 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 94.59 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 150.71 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 219.57 kB +0.12% +242 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 266.18 kB +0.1% +242 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 270.15 kB +0.09% +242 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 279.88 kB +0.09% +242 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 283.84 kB +0.09% +242 B 🔺
@sentry/nextjs (client) 51.36 kB - -
@sentry/sveltekit (client) 46.99 kB - -
@sentry/core/server 78.65 kB - -
@sentry/core/browser 65.08 kB - -
@sentry/node-core 63.21 kB - -
@sentry/node 125.66 kB - -
@sentry/node (incl. diagnostics channel injection) 149.25 kB -0.01% -1 B 🔽
@sentry/node/import (ESM hook with diagnostics-channel injection) 70.03 kB - -
@sentry/node/light 51.32 kB - -
@sentry/node - without tracing 74.92 kB +0.01% +1 B 🔺
@sentry/aws-serverless 84.15 kB - -
@sentry/cloudflare (withSentry) - minified 184 kB - -
@sentry/cloudflare (withSentry) 455.41 kB - -

View base workflow run

Sign up for free to 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.

1 participant