[v2] unhandledrejection bridge brands all page rejections as "QWIK ERROR"
bugruntimeneeds reproductionDXV2
## Which component is affected?
Qwik Runtime (v2 / `build/v2`) — client error handling, added by the ErrorBoundary PR #8745.
## Describe the bug
The window-level bridge in `packages/qwik/src/core/client/dom-container.ts:146` registers `addEventListener('unhandledrejection', (e) => logError(e?.reason))` with **no Qwik-origin filter**, so it fires for *every* unhandled promise rejection on the page — including rejections from third-party scripts or app code unrelated to Qwik. Because `logError` (`shared/utils/log.ts`) prefixes `%cQWIK ERROR` in Qwik's style, a foreign rejection gets **misattributed to Qwik**.
What is already fine (verified, not part of this issue): per-window dedup works (one listener per `view` via a WeakSet; a spec pins exactly-one registration across two containers), and there is no double-log with a boundary-handled error (the boundary path uses `logErrorAndThrowAsync` → `window.onerror`, disjoint from `unhandledrejection`).
## Scope / fix direction
The bridge intentionally routes otherwise-lost fire-and-forget rejections to `logError`/monitoring (an e2e pins this), so the goal is **not** to stop logging — only to stop branding non-Qwik rejections as Qwik. There is no cheap reliable filter today (`e.reason` is opaque with no Qwik marker), so this needs a small design pass, e.g.:
- a neutral log label for rejections not traceable to a Qwik boundary, or
- tag Qwik-originated rejection reasons so only those get the QWIK ERROR branding.
Also consider (but likely **don't**): the bridge does not call `e.preventDefault()`, so a genuine Qwik rejection surfaces twice (native "Uncaught (in promise)" + branded QWIK ERROR). Suppressing the native one would hide the rejection from other tooling (e.g. Sentry's own `unhandledrejection` handler), so leaving it un-suppressed is probably correct — noted here so it's decided deliberately.
Net-new in #8745; DX-only, does not block that PR.
1 条评论