mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2026-10-27 16:02:05 +00:00
fix: a bare seedpass-js printed help and then reported a bogus error
exitOverride() makes commander throw for everything it would otherwise exit on -- displaying help and its own usage errors included. The handler only recognised two of its codes, so running `seedpass-js` with no arguments printed the help and followed it with `error: (outputHelp)`, and unknown commands had their message printed twice. Any commander.* code is now commander's business: honour its exit code and let it own the message. SeedPass's own errors still print as before. Found by running the command. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
1 parent
3a50f57b66
commit
0dfeca8a50
2 files changed
+32
-4
No files matched your search
@@ -10,12 +10,19 @@ program.version(version, "-v, --version", "print the seedpass-js version");
|
||||
try {
|
||||
await program.parseAsync(process.argv);
|
||||
} catch (e) {
|
||||
// commander's exitOverride throws for --help/--version too; those carry
|
||||
// exitCode 0 and must not be reported as errors.
|
||||
const err = e as { exitCode?: number; code?: string; message?: string };
|
||||
if (err.code === "commander.helpDisplayed" || err.code === "commander.version") {
|
||||
process.exit(0);
|
||||
|
||||
// exitOverride() makes commander throw for everything it would otherwise
|
||||
// exit on — including displaying help or the version, and its own usage
|
||||
// errors, which it has already written to stderr. Re-reporting those as
|
||||
// "error: ..." is wrong twice over: a bare `seedpass-js` printed the help
|
||||
// and then claimed to have failed with "(outputHelp)". Honour commander's
|
||||
// exit code, but let it own the message.
|
||||
if (typeof err.code === "string" && err.code.startsWith("commander.")) {
|
||||
process.exit(typeof err.exitCode === "number" ? err.exitCode : 0);
|
||||
}
|
||||
|
||||
// Anything else is ours, and the message is the useful part.
|
||||
process.stderr.write(`error: ${err.message ?? String(e)}\n`);
|
||||
process.exit(typeof err.exitCode === "number" && err.exitCode !== 0 ? err.exitCode : 1);
|
||||
}
|
||||
@@ -434,6 +434,27 @@ describe("document import/export", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("exit behaviour", () => {
|
||||
it("does not report help output as an error", async () => {
|
||||
// exitOverride() makes commander throw when it prints help, so a bare
|
||||
// invocation printed the help and then claimed to have failed with
|
||||
// "(outputHelp)".
|
||||
const out: string[] = [];
|
||||
const err: string[] = [];
|
||||
const io: ProgramIo = { out: (l) => out.push(l), err: (l) => err.push(l) };
|
||||
let thrown: { code?: string; exitCode?: number } | undefined;
|
||||
try {
|
||||
await buildProgram(io).parseAsync(["node", "seedpass-js"]);
|
||||
} catch (e) {
|
||||
thrown = e as { code?: string; exitCode?: number };
|
||||
}
|
||||
// commander signals help with its own code; main.ts must treat any
|
||||
// commander.* code as commander's business, not as a SeedPass error.
|
||||
expect(thrown?.code).toMatch(/^commander\./);
|
||||
expect(err.join("\n")).not.toContain("outputHelp");
|
||||
});
|
||||
});
|
||||
|
||||
describe("error messages", () => {
|
||||
it("explains a corrupt or foreign vault file instead of leaking a codec error", async () => {
|
||||
const dir = await mkdtemp(join(tmpdir(), "seedpass-corrupt-"));
|
||||
|
||||
Reference in new issue
Block a user