QwikDev / QwikDev/qwik

[v2] unhandledrejection bridge brands all page rejections as "QWIK ERROR"

Open
#8,800 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug DX needs reproduction runtime V2
Dominant language
TypeScript
Stars
22.1k
Forks
1.4k
Avg merge
1d 10h
Merged PRs (30d)
52

Description

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 logErrorAndThrowAsyncwindow.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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/qwik/src/core/client/dom-container.ts:146 and read the unhandledrejection bridge together with shared/utils/log.ts. Review the existing one-listener spec and the e2e coverage that preserves logging, then decide how Qwik-originated and foreign rejections should be distinguished. Done means non-Qwik rejections are no longer branded QWIK ERROR while Qwik rejection logging and monitoring remain covered.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
developer-experience, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.