You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(extension): bound every network and storage read the UI opens with
The side panel opened to a header and nothing else, and the New Tab page sat
on its placeholders with the tab spinner running. Both surfaces render by
awaiting a chain of calls, and most of those calls could not fail.
`fetch()` has no default timeout. A host that accepts the connection and then
never answers leaves the promise pending for the life of the tab, so the
section waiting on it never renders and never errors — it just stays blank.
Nine of these were on a render path: the MOTD, Yahoo quotes, ESPN scores,
bittorrented `/me` and `/favorites`, CoinPay `/auth/me`, `/login`, `/signup`,
`/logout`, the settings pull/push, and the provider model list.
background.js, moshpit.js and the per-feed fetch already each carried their
own AbortController for exactly this reason; this is that pattern, in one
place, for the rest of them.
chrome.storage.local is bounded for the same reason. It is backed by a LevelDB
in the profile, and a large or damaged one can leave a get() pending. In the
side panel that read is `aiConfig`, and until it resolves the setup prompt
stays hidden and the panel shows nothing — a stalled read decided whether the
UI appeared at all. It now falls back to {} after 3s, which every caller
already handles as "nothing stored", so the panel draws its unconfigured
state instead of staying blank.
Streaming chat calls in providers.js are deliberately left unbounded — a long
completion is not a hang.
Tests: 9 covering the timeout, pass-through, real-error and fallback paths.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
0 commit comments