feat(remix): Capture Remix 3 component render errors - #24873
Conversation
|
bugbot run |
There was a problem hiding this comment.
✅ 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.
size-limit report 📦
|
9b3ebde to
f33fbed
Compare
1012e6a to
be85720
Compare
| function readComponentError(event: Event): unknown { | ||
| const error = (event as ErrorEvent).error; | ||
| return error !== undefined ? error : event; | ||
| } |
There was a problem hiding this comment.
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.
ee57253 to
c9a8569
Compare
c9a8569 to
cd5e136
Compare
| return channel; | ||
| } | ||
|
|
||
| export default { tracingChannel }; |
There was a problem hiding this comment.
We do both, no specific reason here
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>
cd5e136 to
e6c1bd3
Compare
The
remix/uiruntime sends every render, scheduler, frame and hydration error to the event targetrun()returns, and dispatching an event does not rethrow. Sowindow.onerrorandunhandledrejectionnever 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