Skip to content

fix(web): surface swallowed errors and close the microphone on failure - #167

Merged
TheGreatAxios merged 8 commits into
mainfrom
cl-12110-remove-swallowed-errors-unchecked-casts-and-iifes-from-the
Nov 4, 2026
Merged

TheGreatAxios merged 8 commits into
mainfrom
cl-12110-remove-swallowed-errors-unchecked-casts-and-iifes-from-the

Conversation

@TheGreatAxios

@TheGreatAxios TheGreatAxios commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

First of the CL-12110 pull requests: the swallowed errors, the microphone leak and the floating promises from the Findings document.

Changes

  • Dictation opens the microphone and its level meter in openMicrophone. When the AudioContext fails after the microphone opens, its tracks are stopped and the context closed, so the microphone no longer stays on.
  • The hub session read throws ApiFailure: unreachable and 5xx are retryable and stay the loading screen's to show; any other failure is now toasted (before, every failure was dropped because it was a plain Error). The fetch failure keeps its cause, and only a SyntaxError from a non-JSON auth body is ignored. A connection that drops while the body is read counts as unreachable too.
  • Sign-out failure and a refused or missing clipboard now show a toast. The document retry is awaited, so a failed project read during it is toasted instead of becoming an unhandled rejection; a document that fails again still shows its own error state.
  • Project import maps only an unreadable zip (opening it or inflating project.json) or a SyntaxError to "invalid import"; anything else propagates. ApiFailure takes ErrorOptions so the cause is kept.
  • The invitation role-name read expects 403 and 404 and logs any other failure; the role name stays a courtesy and never blocks the page.
  • A PDF whose base64 does not decode no longer becomes an empty file: the PDF view says it could not be read and offers no download.
  • JSON.parse catches in visible-chat.ts and dispatch-card.tsx catch only SyntaxError. The sessionStorage catches in model-setup.tsx log the cause, as stored-preference.ts does.
  • void cause and void receipt are gone, and the invitation load is a named function instead of an IIFE (Triage flagged it because the role-name catch sits inside it). The open-decisions re-read logs its cause and keeps the cached list.

Turned out safe, changed for the pattern only

  • room-reload.ts:31: with no room on screen, loadProjectRoom already fails the room query with the same cause, which shows the room fault. The reloader now logs instead of .catch(() => undefined).

Left for the later CL-12110 pull requests: the JSON.parse catches that also need arktype (design-preview, specialist-updates, seen-versions, run-stream) (untrusted JSON); the remaining promise chains, .catch() calls and IIFEs, including App.tsx's getHubSession/ensureWorkspace chains (promise chains). Dictation's microphone outliving an unmount during openMicrophone predates this and belongs to CL-12096.

Verification

  • New tests: a damaged zip entry is refused as an invalid import (fails on the earlier commit with JSZip's raw error); a failing AudioContext stops the microphone tracks; a bad PDF base64 shows the unreadable line and no download.
  • bun run lint, format:check, typecheck, test, pins:verify and vendor:verify pass.

@linear-code

linear-code Bot commented Nov 4, 2026

Copy link
Copy Markdown

CL-12110

@TheGreatAxios
TheGreatAxios marked this pull request as ready for review November 4, 2026 21:23

@corbits-triage corbits-triage Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Triage requests changes:

  • Conventions: added code matches a code pattern
    • apps/web/src/pages/invite-accept.tsx:30-64 iife: Immediately invoked function; name the function.

Comment thread apps/web/src/App.tsx Resolved

@corbits-triage corbits-triage Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Triage requests changes:

  • Merge conflicts: merge conflicts with base

* fix(web): handle missing room data instead of inventing it

* fix(web): start room reads early and keep unread decisions unknown

* fix(web): name an approval without concepts instead of defaulting

* fix(web): ask about a blank-named document by its tool
* fix(web): rethrow failures other than unreadable JSON or cache

* refactor(web): replace promise chains and an IIFE with named functions

* refactor(web): poll a subscription login with a query observer

* fix(web): treat an unreadable refusal body as one without a code

* fix(web): never hold the first paint on a failed cache restore

* fix(web): keep a login poll running offline and out of the cache

* refactor(web): share one version read between view and compare
* fix(web): check untrusted JSON and hub values against their schemas

* fix(web): treat an unreadable session as an error, not a sign-out

* fix(web): read a frame's missing text without inventing one

* fix: refuse unreadable custom models and unknown login URLs (#170)

* fix(client): read login base URLs from a map keyed by login plugin

* fix(web): refuse unreadable custom models instead of sending null
@TheGreatAxios
TheGreatAxios force-pushed the cl-12110-remove-swallowed-errors-unchecked-casts-and-iifes-from-the branch from 10cf13f to c1de195 Compare November 4, 2026 22:43
@corbits-triage

corbits-triage Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Merged before Triage finished on c1de195.

@TheGreatAxios
TheGreatAxios merged commit 9ba3e91 into main Nov 4, 2026
9 checks passed
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