Robinhood connection: no more stuck "Connecting…"
This release fixes a class of Robinhood connect failures seen during onboarding, and adds a way out when a consent flow is abandoned.
Fixed
- Connect could hang forever after closing the Robinhood tab. The OAuth consent waited on a fixed local port with no timeout and no way to cancel; a closed browser tab left the daemon spinning on "connecting" for the life of the process, and every later Connect failed with
EADDRINUSE. The loopback now binds an ephemeral port per consent (RFC 8252 §7.3), only proceeds once it is actually listening, and times out after 10 minutes. - A second Connect click no longer collides with a pending one — it supersedes it: the abandoned attempt is cancelled and a fresh consent starts, whether the click comes from Onboarding, Settings, or the Portfolio panel.
- Silent reconnect at launch never opens a browser unprompted, and no longer drops still-valid tokens when a token refresh fails for a transient reason (network / 5xx). You re-consent explicitly via Connect.
- Bare
Errorlistener failures during connect no longer surface as unhandled rejections.
Added
- Cancel / Disconnect. While a consent is waiting on the browser, all three Connect surfaces show "Waiting for Robinhood…" with a Cancel button (including Onboarding, where Settings isn't reachable). Settings → Market data gets a Disconnect button when connected — also how to switch Robinhood accounts.
Telemetry
app_errorandbroker_connect_failednow carry a boundederror_code(e.g.EADDRINUSE,OAUTH_ACCESS_DENIED) — the machine code only, never a message or path — so async Node system errors, whose stacks have no app frames, are diagnosable.
Upgrade notes
No schema or data migration. Existing installs keep their Robinhood session and refresh silently as before.
Full Changelog: v0.2.2...v0.2.3