fix(web): mint PROVIDER_NOT_FOUND; push refusals reach the caller - #345
Conversation
Two things, one of them a correction to my own code in #344. PROVIDER_NOT_FOUND. I used INVALID_FORMAT for an unknown provider, which is wrong: that is a not-found condition, not a malformed one, and the remedies differ — "pick from the list" versus "correct your syntax". A caller branching on the code cannot tell those apart, and the code is the contract; that is the whole reason we do not parse the prose. Minted at the point the condition is first known, per the rule KEY_NOT_ON_DEVICE's own comment states, and alongside the existing not-found family. push. Found by RUNNING commands under --web with no TTY rather than reading them: `capy push --web` refused with exit 1 and no URL anywhere. It was on nobody's list. Both its guards now throw into the catch that execute() already routes to displayErrorAndExit. push takes no `web` option and needs none — that function reads web mode itself. Verified by running, not inferred: $ capy push --web # clean HOME exit code: 1 url line : http://127.0.0.1:60064/s/G5BjAmn9Owi7-uZY9PR3pPqnL85M8tIprJ96XX3qne0 Before this it printed the refusal and nothing else. Suite: 1851 pass, 0 fail. A first run exited 1 on tests/auth/authServiceKeepScreens.test.ts; that file passes in isolation on this tree and a second full run was clean, so it is order-dependent flake, not this change — the diff touches only push, connect and the code table.
ExitPromptError audit — answer to "which sites can be reached with no TTY under
|
| command | exit | URL |
|---|---|---|
deploy |
1 | yes |
decrypt |
1 | yes |
branch |
1 | yes |
checkout somebranch |
1 | yes |
redeem |
serves page | yes |
byoc |
serves page | yes |
kick <email>, org |
auth path | yes |
push |
1 | NO — fixed in this PR |
flow cancel <id> |
3 | NO — see below |
Not one exits 0 with no URL. The silent-success class you described is real in shape, but I cannot reach it on any path a clean HOME can produce. The ExitPromptError handlers only fire once an interactive prompt is actually reached, and every command I can invoke refuses at auth or project state before prompting. Reaching them needs a signed-in session with a project — which I cannot construct here.
The site inventory, for when someone can reach them
Three handlings, as you said:
- exit 0 directly:
errorScreen.ts:117,deployTokenCommand.ts:645,index.ts×2,index-dev.ts×2,decryptCommand.ts:301 - rethrow (correct — lets the outer handler decide):
kickCommand:44,orgCommand:72 - pre-empted upstream:
capyCommand.ts:686-700, which detects no-TTY before the keypress read. Its comment is right that catching at the read is already too late.
Candidate files where a prompt exists with little or no web-awareness, i.e. where an unguarded read could still fire: githubActionsConnector.ts (4 prompts, 0 web checks), orgCreation.ts, redeemCommand.ts, flowCancelCommand.ts, byocCommand.ts (10 prompts, 1 check), deployCommand.ts (18 prompts, 3 checks). I am not reporting these as defects — a file having no web check does not mean the path is reachable under --web, and tonight has repeatedly shown source sweeps over-report.
One genuine finding I am not fixing unilaterally
capy flow cancel <id> --web exits 3 with no URL. That is not the silent class — it refuses loudly and names the remedy (--yes), which is the correct non-interactive pattern. But under --web the refusal still reaches nobody. Fixing it means deciding whether a refusal that already behaves correctly for a terminal also owes a page. Your call.
capy deploy --web, run again just now
COMMAND: capy-staging deploy --web
EXIT CODE: 1
URL LINE: http://127.0.0.1:64892/s/y7W5k7l8HQbcK_YkVbdDSTX1e4hjZIdRIJNULodWCag
Nothing blocks it. That is the 10th run.
Two things, one a correction to my own code in #344.
PROVIDER_NOT_FOUNDI used
INVALID_FORMATfor an unknown provider. Wrong: that is a not-found condition, not a malformed one, and the remedies differ — "pick from the list" versus "correct your syntax". A caller branching on the code cannot tell those apart, and the code is the contract; that is the whole reason we do not parse prose. Minted at the point the condition is first known, alongside the existing not-found family.pushFound by running commands under
--webwith no TTY, not by reading them.capy push --webrefused with exit 1 and no URL anywhere. It was on nobody's list — not mine, not the audit's.Both guards now throw into the catch
execute()already routes todisplayErrorAndExit.pushtakes noweboption and needs none: that function reads web mode itself.Verified by running:
Before this it printed the refusal and nothing else.
Suite
1851 pass, 0 fail. A first run exited 1 on
tests/auth/authServiceKeepScreens.test.ts; that file passes in isolation on this tree and a second full run was clean, so it is order-dependent flake rather than this change — the diff touches onlypush,connectand the code table. Flagging it rather than quietly re-running until green.