fix(tutor): propagate chatStream bridge-not-ready as a rejection (stranded spinner)#174
Merged
Merged
Conversation
… 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
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 synchronousthrow 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'sawaitresolved, its catch never ran,onChunknever 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
isReadyis false) · eslint · prettier · local E2Etutor-chat+stream-cancelpass.🤖 Generated with Claude Code