Skip to content

feat(remix): Capture Remix 3 component render errors - #24873

Merged
chargome merged 1 commit into
developfrom
charlygomez/js-3768-remix-3-client-error-capture
Oct 1, 2026
Merged

chargome merged 1 commit into
developfrom
charlygomez/js-3768-remix-3-client-error-capture

Conversation

@chargome

@chargome chargome commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

The remix/ui runtime sends every render, scheduler, frame and hydration error to the event target run() returns, and dispatching an event does not rethrow. So window.onerror and unhandledrejection never see them, and the default browser integrations report nothing from the component layer. Removing the listener added here makes the new e2e test fail.

Costs 0.27 KB gzipped in the client bundle, inside the existing budget.

Fixes #24665

@chargome chargome self-assigned this Sep 30, 2026
@linear-code

linear-code Bot commented Sep 30, 2026

Copy link
Copy Markdown

JS-3768

@chargome

Copy link
Copy Markdown
Member Author

bugbot run

@chargome
chargome added this pull request to stack #24875 September 30, 2026 09:46

@cursor cursor Bot 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 9b3ebde. Configure here.

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 29.51 kB - -
@sentry/browser - with treeshaking flags 27.68 kB - -
@sentry/browser - with treeshaking flags tracing without tracing 27.58 kB - -
@sentry/browser (incl. Tracing) 51.46 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 51.47 kB - -
@sentry/browser (incl. Tracing, Profiling) 54.47 kB - -
@sentry/browser (incl. Tracing, Replay) 91.05 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 80.03 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 95.73 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 108.72 kB - -
@sentry/browser (incl. Feedback) 47.04 kB - -
@sentry/browser (incl. sendFeedback) 34.57 kB - -
@sentry/browser (incl. FeedbackAsync) 39.69 kB - -
@sentry/browser (incl. Metrics) 30.53 kB - -
@sentry/browser (incl. Logs) 30.82 kB - -
@sentry/browser (incl. Metrics & Logs) 31.48 kB - -
@sentry/react 31.36 kB - -
@sentry/react (incl. Tracing) 53.82 kB - -
@sentry/vue 37.51 kB - -
@sentry/vue (incl. Tracing) 54.36 kB - -
@sentry/svelte 29.54 kB - -
@sentry/remix (Remix 3 client bundle) 55.75 kB +0.52% +284 B 🔺
CDN Bundle 31.22 kB - -
CDN Bundle (incl. Tracing) 51.99 kB - -
CDN Bundle (incl. Logs, Metrics) 33.46 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 53.94 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 74.2 kB - -
CDN Bundle (incl. Tracing, Replay) 89.56 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 91.54 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 95.73 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 97.73 kB - -
CDN Bundle - uncompressed 92.14 kB - -
CDN Bundle (incl. Tracing) - uncompressed 154.53 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 98.71 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 160.48 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 228.28 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 274.26 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 280.2 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 287.96 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 293.89 kB - -
@sentry/nextjs (client) 56.33 kB - -
@sentry/sveltekit (client) 51.88 kB - -
@sentry/core/server 39.99 kB - -
@sentry/core/browser 13.63 kB - -
@sentry/node 144.32 kB +0.01% +7 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 83.01 kB - -
@sentry/node - without tracing 92.96 kB +0.02% +10 B 🔺
@sentry/node - without channel injection 122.66 kB +0.01% +11 B 🔺
@sentry/aws-serverless 101.26 kB +0.01% +8 B 🔺
@sentry/cloudflare (withSentry) - minified 206.83 kB - -
@sentry/cloudflare (withSentry) 514.6 kB - -

View base workflow run

@chargome
chargome removed this pull request from stack #24875 September 30, 2026 11:41
@chargome
chargome added this pull request to stack #24884 September 30, 2026 11:41
@chargome
chargome marked this pull request as ready for review September 30, 2026 13:14
@chargome
chargome requested a review from a team as a code owner September 30, 2026 13:14
@chargome
chargome requested review from nicohrubec and s1gr1d and removed request for a team September 30, 2026 13:14
@chargome
chargome force-pushed the charlygomez/js-3768-remix-3-client-error-capture branch from 9b3ebde to f33fbed Compare September 30, 2026 13:41
@chargome
chargome force-pushed the charlygomez/js-3768-remix-3-client-error-capture branch 2 times, most recently from 1012e6a to be85720 Compare September 30, 2026 14:23
Comment on lines +71 to +74
function readComponentError(event: Event): unknown {
const error = (event as ErrorEvent).error;
return error !== undefined ? error : event;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Bug: The null check in readComponentError is incorrect for cross-origin errors, where error can be null. This causes loss of error context when reporting.
Severity: MEDIUM

Suggested Fix

Update the condition in readComponentError to handle both null and undefined values for the error property. Changing the check from error !== undefined to error != null will ensure that the function correctly falls back to returning the event object itself in cases of cross-origin errors.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: packages/remix/src/v3/client/errors.ts#L71-L74

Potential issue: The `readComponentError` function checks for an error object on an
event using `error !== undefined`. For cross-origin script errors, browsers often set
the `error` property to `null`. The current check incorrectly passes this `null` value
to `captureException`, which then creates a generic error report with the message
"null". This results in the loss of valuable context from the original event object,
hindering debugging efforts for cross-origin errors.

Did we get this right? 👍 / 👎 to inform future reviews.

@chargome
chargome force-pushed the charlygomez/js-3768-remix-3-client-error-capture branch 2 times, most recently from ee57253 to c9a8569 Compare September 30, 2026 15:01
@chargome
chargome force-pushed the charlygomez/js-3768-remix-3-client-error-capture branch from c9a8569 to cd5e136 Compare October 1, 2026 08:12
Comment thread packages/remix/src/v3/client/diagnosticsChannelShim.ts
return channel;
}

export default { tracingChannel };

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why not do a named export?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We do both, no specific reason here

Base automatically changed from charlygomez/js-3768-add-remix-3-browser-sdk-with-a-bundled-client-entry to develop October 1, 2026 13:33
The `remix/ui` runtime sends every render, scheduler, frame and hydration
error to the event target `run()` returns, and dispatching an event does
not rethrow. So `window.onerror` and `unhandledrejection` never see them,
and the default browser integrations report nothing from the component
layer. Removing the listener added here makes the new e2e test fail,
which is the cheapest proof of that.

The `diagnostics_channel` browser shim ships as its own file because the
browser transform imports it by URL, so an inlined copy would leave the
page with two subscriber registries. Its subscription is dormant until
that transform lands.

Costs 0.27 KB gzipped in the client bundle, which stays inside the
existing budget.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chargome
chargome force-pushed the charlygomez/js-3768-remix-3-client-error-capture branch from cd5e136 to e6c1bd3 Compare October 1, 2026 13:33
@chargome
chargome merged commit 563e333 into develop Oct 1, 2026
51 checks passed
@chargome
chargome deleted the charlygomez/js-3768-remix-3-client-error-capture branch October 1, 2026 15:09
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.

Add Remix 3 browser SDK with a bundled client entry

2 participants