-
Notifications
You must be signed in to change notification settings - Fork 17
fix(npm): mirror the binary's exit status instead of throwing a Node stack trace - #276
Hidden character warning
Conversation
Review Council round closed without a verdict — superseded by a newer round or timed out.
Review Council started (round 1).
Baseline:
- Scope: 5 files changed (+94/−2)
- CI/checks: pending (0 contexts) at
2ee029f
The council is reviewing this pull request; the verdict will follow as a separate comment when the round closes.
|
LGTM ✅ — A tightly-scoped npm-wrapper fix that mirrors the binary's real exit status; both reviewers approve with no actionable findings and CI is green. What This PR Does
How It Works
Findings
Finding Details🟢 F1: Exit-status branch mapping is correctrev-claude traced Node's 🟢 F2: No security regression in the changed surfacerev-codex confirmed arguments stay argv-separated through 🟢 F3: Packaging and CI wiring are correctThe test is un-ignored in 🟢 F4: Minor out-of-scope churnThe root What's Good (🟢)
Baseline Check
Review Metadata
×ばつ0 ×ばつ0 ×ばつ4 · 💬 Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Council approve — 🔴0 🟡0 🟢4. Reviewed at 2ee029f. Full report: #276 (comment)
2ee029f to
f8125cc
Compare
Review Council round closed without a verdict — superseded by a newer round or timed out.
...stack trace `npx zeabur ...` runs npm/index.js, which spawned the Go binary with execFileSync and never caught the throw on a non-zero exit. Two things went wrong every time the CLI failed: Node printed an uncaught-exception stack trace whose error object carried `stdout: null, stderr: null` (stdio is inherited, so the real output had already gone to the terminal), and the process exit code became 1 regardless of what the binary returned. An agent reading that saw "exec produced nothing" instead of psql's actual `role "postgres" does not exist` (exit 2). The wrapper now exits with the binary's status; a signal death maps to the shell convention 128+signal; a spawn failure (e.g. missing binary) prints one line and exits 1. Refs DES-909 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
f8125cc to
729d3bd
Compare
Review Council started (round 2).
Baseline:
- Scope: 1 files changed (+17/−1)
- CI/checks: pending (0 contexts) at
729d3bd
The council is reviewing this pull request; the verdict will follow as a separate comment when the round closes.
|
CHANGES REQUESTED Delta since 2ee029f (prior round, unreachable)The prior reviewed head
Findings
Finding Details🟡 F5: Regression test and CI coverage removed by the branch rewriterev-claude found — and the chair independently confirmed — that Concrete action: restore 🟢 F1: Exit-status branch mapping is correct (unchanged)Both reviewers re-confirmed the try/catch partitions Node's 🟢 F2: No security regressionrev-codex verified the wrapper still invokes a fixed package-relative binary with no shell, user arguments stay argv-separated, executable selection is not user-redirectable, and the exception path discloses only the ordinary error message — no stack-trace or secret exposure, no fail-open. What's Good (🟢)
Baseline Check
Review Metadata
×ばつ0 ×ばつ1 ×ばつ2 · 💬 Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Council request_changes — 🔴0 🟡1 🟢2. Reviewed at 729d3bd. Full report: #276 (comment)
## Summary - `cmd/main.go` logged the error from `rootCmd.Execute()` and then returned normally, so every failure exited 0: unknown command, unknown flag, API 401, missing workspace. Shells (`set -e`, `&&`), CI and the agent sandbox's bash tool all key off the exit status, so failed `zeabur` calls looked like successes. #276 made the npm wrapper mirror the binary's status, which exposed this. - Fix: `os.Exit(1)` after logging. Output format is unchanged (same `ERROR` line on stderr, `--json` unaffected). Commands that already set their own status (`service exec`, `server exec` forward the remote exit code) are untouched. ## Test plan - [x] `make test`, `make build` pass - [x] Built binary, `ZEABUR_TOKEN=zat_bogus`, clean HOME: `bogus-command` → 1, `version --no-such-flag` → 1, `profile info` (401) → 1, `project list --workspace does-not-exist` → 1, `project list` (401) → 1, `version` → 0 - [ ] After release: `npx zeabur@latest bogus-command; echo $?` prints 1 ## Noticed, not fixed here - With no token and `-i=false`, `zeabur profile info` blocks waiting for the browser login callback instead of failing fast. Non-interactive mode should error out; separate issue. Generated with [Claude Code](https://claude.com/claude-code)
Uh oh!
There was an error while loading. Please reload this page.
Summary
npm/index.js(whatnpx zeaburruns) letexecFileSyncthrow on any non-zero exit: Node printed an uncaught-exception stack trace withstdout: null, stderr: null(stdio is inherited, so the real output had already been printed) and the exit code collapsed to 1. An agent reading that concluded "exec produced nothing" instead of seeing psql's realrole "postgres" does not exist(exit 2) — DES-909.128 + signal; a spawn failure (missing binary) prints one line and exits 1. stdio passes through exactly as before.Test plan
index.jsnext to a fake binary:exit 2→ exit code 2 with only the binary's stderr; success → exit 0 with stdout/stderr passed through; missing binary → one-line message, exit 1make build,make testunchanged (the wrapper is not part of the Go build)npx zeabur@latest service exec ... -- sh -c 'exit 2'returns 2 with no Node stack traceRefs DES-909
Generated with Claude Code