diff --git a/mod.test.ts b/mod.test.ts index b06a227..4606efc 100644 --- a/mod.test.ts +++ b/mod.test.ts @@ -587,6 +587,18 @@ Deno.test("exit command", async () => { assertEquals(result.code, 2); assertEquals(result.stderr, "exit: too many arguments\n"); } + // test noThrow with exit code + { + const result = await $`exit 255`.noThrow(255); + assertEquals(result.code, 255); + } + { + const result = await $`exit 255`.noThrow(254, 255); + assertEquals(result.code, 255); + } + { + await assertRejects(() => $`exit 255`.noThrow(254)); + } }); Deno.test("should provide result from one command to another", async () => { diff --git a/src/command.ts b/src/command.ts index 8dd5aa6..981b17e 100644 --- a/src/command.ts +++ b/src/command.ts @@ -39,7 +39,7 @@ interface CommandBuilderState { combinedStdoutStderr: boolean; stdoutKind: ShellPipeWriterKind; stderrKind: ShellPipeWriterKind; - noThrow: boolean; + noThrow: boolean | number[]; env: Record; commands: Record; cwd: string | undefined; @@ -120,7 +120,7 @@ export class CommandBuilder implements PromiseLike { stdin: state.stdin, stdoutKind: state.stdoutKind, stderrKind: state.stderrKind, - noThrow: state.noThrow, + noThrow: state.noThrow instanceof Array ? [...state.noThrow] : state.noThrow, env: { ...state.env }, cwd: state.cwd, commands: { ...state.commands }, @@ -200,10 +200,17 @@ export class CommandBuilder implements PromiseLike { }); } + /** The command should not throw for the provided non-zero exit codes. */ + noThrow(exclusionExitCode: number, ...additional: number[]): CommandBuilder; /** The command should not throw when it fails or times out. */ - noThrow(value = true): CommandBuilder { + noThrow(value?: boolean): CommandBuilder; + noThrow(value?: boolean | number, ...additional: number[]): CommandBuilder { return this.#newWithState((state) => { - state.noThrow = value; + if (typeof value === "boolean" || value == null) { + state.noThrow = value ?? true; + } else { + state.noThrow = [value, ...additional]; + } }); } @@ -621,7 +628,8 @@ export function parseAndSpawnCommand(state: CommandBuilderState) { // override the code in the case of a timeout that resulted in a failure code = 124; } - if (!state.noThrow) { + const noThrow = state.noThrow instanceof Array ? state.noThrow.includes(code) : state.noThrow; + if (!noThrow) { if (stdin instanceof ReadableStream) { if (!stdin.locked) { stdin.cancel();