Skip to content

fix(tutor): propagate chatStream bridge-not-ready as a rejection (stranded spinner)#174

Merged
heznpc merged 1 commit into
mainfrom
fix/chatstream-stranded-spinner-v2
Jun 4, 2026
Merged

fix(tutor): propagate chatStream bridge-not-ready as a rejection (stranded spinner)#174
heznpc merged 1 commit into
mainfrom
fix/chatstream-stranded-spinner-v2

Conversation

@heznpc

@heznpc heznpc commented Jun 4, 2026

Copy link
Copy Markdown
Owner

Re-opened cleanly from main (the original #173 got tangled with #172's protected-terms changes via a branch-base race; #173 was closed).

Confirmed bug

chatStream's try/catch caught the synchronous throw new Error('Bridge not ready') (Puter bridge handshake not finished — reachable on cold start / slow-or-blocked CDN / non-trusted host) and resolved to an error string. But the sole caller (sidebar-chat.js:381) discards chatStream's return value and relies on a thrown error to render the error bubble + retry. So on bridge-not-ready the caller's await resolved, its catch never ran, onChunk never fired → the "thinking…" spinner stranded forever, no error, no retry. The E2E helpers even document the intended behavior as "chatStream throws 'Bridge not ready'".

Fix

Re-throw from the catch so the synchronous setup failure propagates as a rejection and the caller's existing error+retry path handles it. Promise-path failures (timeout/abort/success:false) already reject and are unaffected.

Verification

493 unit tests (incl. new regression: chatStream rejects when isReady is false) · eslint · prettier · local E2E tutor-chat + stream-cancel pass.

🤖 Generated with Claude Code

… a string

Confirmed by a service-quality audit. chatStream's try/catch caught the
synchronous `throw new Error('Bridge not ready')` (Puter bridge handshake not
finished — reachable on cold start / slow or blocked CDN / non-trusted host) and
RESOLVED to a localized error string. But the sole caller (sidebar-chat.js:381)
discards chatStream's return value and relies on a thrown error to render the
error bubble + retry button. So on bridge-not-ready: the caller's await resolved
normally, its catch never ran, onChunk never fired — leaving the "thinking…"
spinner stranded forever with no error and no retry. The E2E helpers even
document the intended behavior as "chatStream throws 'Bridge not ready'".

Fix: re-throw from the catch instead of returning a string, so the synchronous
setup failure propagates as a promise rejection and the caller's existing
error+retry path handles it. Promise-path failures (timeout, abort,
success:false) already reject and are unaffected.

Added a regression test asserting chatStream rejects (not resolves) when
isReady is false. 493 tests, eslint, prettier green.
@heznpc heznpc enabled auto-merge (squash) June 4, 2026 11:29
@heznpc heznpc merged commit 76f7b08 into main Jun 4, 2026
8 checks passed
@heznpc heznpc deleted the fix/chatstream-stranded-spinner-v2 branch June 4, 2026 11:30
heznpc added a commit that referenced this pull request Jun 9, 2026
…tency) (#181)

A verified readiness audit found the code is done (505 tests, 0 open issues)
but front-door docs had drifted. Fixes (all factual/compliance, not the
deferred strategy docs):

Factual errors (were misleading users/owner):
- README Installation said the CWS listing "was removed ... not currently
  available" (full delisting). It is actually live as v1.0.1 in all locales
  except the US (removed 2026-05-12 over the old icon). Corrected to match
  POSITIONING (the source of truth).
- RELEASE_CHECKLIST pointed at store-assets/promotion/ drafts that were purged
  and no longer exist. Removed the dead pointer (drafts are kept off-repo).

Stale (now closed):
- CHANGELOG [Unreleased] was missing #167/#170/#172/#174/#175/#176/#179/#180;
  added them.
- it.json _meta.translation_provenance + lastUpdated (and the matching
  constants.js comment, README locale-table cell) still said "v1, Spanish-
  derived regex" — it was re-translated from English in #166/#167 (overlap
  now 0.1%). Updated; regenerated plugin data accordingly.
- TESTING.md listed "E2E flows" under "What is NOT tested" — the Playwright
  E2E suite exists and runs in CI. Reframed to describe what E2E covers.
- PRIVACY_POLICY "Last updated" dateline was April 11 despite June changes.

Gates green: 505 tests, lint, prettier, validate, check:plugin/dicts/locales/
i18n/dict-coverage, full E2E (17). Deferred strategy docs (POSITIONING,
quarter-focus) untouched — owned by the separate doc-cleanup session.
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