Skip to content

fix(sync): setup error handling, Windows browser open, themed callback pages#804

Open
Enclavet wants to merge 1 commit into
getagentseal:mainfrom
Enclavet:fix-sync-setup-ux
Open

fix(sync): setup error handling, Windows browser open, themed callback pages#804
Enclavet wants to merge 1 commit into
getagentseal:mainfrom
Enclavet:fix-sync-setup-ux

Conversation

@Enclavet

Copy link
Copy Markdown

Three fixes to the codeburn sync setup login flow based on user feedback.

1. Login timeout crashed Node with a raw stack trace

When the 5-minute login window expired, sync setup died like this:

Waiting for login (5 min timeout)...
file:///.../codeburn/dist/main.js:32406
      reject(new AuthError("Login timed out after 5 minutes. Please try again."));
             ^
AuthError: Login timed out after 5 minutes. Please try again.
    at Timeout._onTimeout (...)

The setup action had no error handling (unlike push), so the rejection
escaped as an unhandled promise rejection. Now:

  • Known errors (AuthError, DiscoveryError — login timeout, callback port
    exhaustion, discovery/OIDC failures) print a clean one-line
    Error: <message> and exit 1.
  • Unexpected errors still print a stack for debuggability.
  • Fixed a latent double-rejection: when all callback ports are in use, both
    the ready promise and the callback promise reject; the second one could
    crash the process as a separate unhandled rejection. The callback promise
    is now marked handled while await semantics are preserved.

2. Windows: browser opened the auth URL with no query parameters

On Windows the browser opened, but the IdP showed a "no parameters" error.

Cause: the URL was launched via cmd /c start "" <url>. cmd.exe splits its
command line on &, so the OAuth query string was truncated at the first
parameter — the IdP received a bare /authorize with no client_id,
redirect_uri, or PKCE challenge, and cmd tried to execute the leftover
fragments as commands.

Fix: launch via rundll32 url.dll,FileProtocolHandler <url>, which receives
the URL as a plain process argument with no shell parsing, putting Windows on
the same footing as macOS (open) and Linux (xdg-open).

Verified on Windows 11: rundll32 url.dll,FileProtocolHandler "https://example.com/?a=1&b=2&c=3" opens the browser with all parameters
intact, and the equivalent execFileSync call (the exact code path) does too.

3. Themed callback landing pages

The success/failure pages were unstyled <h1> markup. They now match the
dashboard theme (dash/src/index.css — warm paper surfaces, ink text,
forest-green success / terracotta failure), via a new renderCallbackPage()
in src/sync/auth.ts. Everything is inline: the page is served once from a
throwaway localhost server, so it has no network font, external CSS, or asset
dependencies.

Testing

All three fixes were manually verified end-to-end, and the full test suite was run.

Manual verification:

  • Timeout path: let the 5-minute login window expire — clean one-line error
    and exit 1, no stack trace (previously crashed Node).
  • Windows browser open: confirmed on Windows 11 that
    rundll32 url.dll,FileProtocolHandler "https://example.com/?a=1&b=2&c=3"
    opens the browser with all query parameters intact, and the exact
    execFileSync call used by the fix behaves the same. The old
    cmd /c start path reproduces the truncation.
  • Themed callback pages: verified rendering of both the success and failure
    states.
  • macOS flow re-tested end-to-end: unaffected (open already passed the URL
    as a direct argument).

Automated:

  • npx tsc --noEmit clean
  • Full suite (npx vitest run, 217 files / 2456 tests): 2440 passed,
    11 failed, 5 skipped. All failures are pre-existing on main or
    load-order flakes — verified by running the same failing files on main
    (identical failures: cursor-real-tokens, parser-proxy-pricing) and in
    isolation on this branch (the CLI/menubar files pass). None touch sync.
  • All 48 sync tests pass (tests/sync.test.ts, tests/sync-e2e.test.ts,
    tests/sync-push.test.ts), including the callback-server timeout test.

…k pages

- Catch errors in 'sync setup' action: AuthError/DiscoveryError (login
  timeout, port exhaustion, discovery failures) now print a clean one-line
  message and exit 1 instead of crashing Node with an unhandled rejection
  stack trace. Also guard the double rejection when all callback ports are
  in use (both 'ready' and the callback promise reject).
- Windows: open the auth URL via 'rundll32 url.dll,FileProtocolHandler'
  instead of 'cmd /c start'. cmd.exe splits its command line on '&', which
  truncated the OAuth query string at the first parameter, so the IdP
  received a bare /authorize request ('no parameters'). rundll32 receives
  the URL as a plain process argument with no shell parsing.
- Theme the OAuth callback landing pages to match the dashboard (warm
  paper background, ink text, forest-green success / terracotta failure),
  fully inline with no network or asset dependencies.

AI-Origin: human
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.

2 participants