Skip to content

Commit

Permalink
feat: throw on non-zero exit
Browse files Browse the repository at this point in the history
This is a breaking change which causes the process to throw when a
non-zero exit code is encountered.

If the exit code is `null`, we will not throw since it means something
went very wrong anyway (the process is still running and shouldn't be,
since we saw the `close` event by then).

If the exit code is greater than `0`, we will throw a
`NonZeroExitError` which has an `exitCode` property.

For example:

```ts
try {
  await x('foo');
} catch (err) {
  if (err instanceof NonZeroExitCode) {
    err.exitCode; // the exit code
    err.result; // the tinyexec process
    err.result.killed; // getters on tinyexec process
  }
}
```
  • Loading branch information
43081j committed Aug 22, 2024
1 parent 64154fe commit 11449ee
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
11 changes: 11 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import {computeEnv} from './env.js';
import {combineStreams} from './stream.js';
import readline from 'node:readline';
import {_parse} from 'cross-spawn';
import {NonZeroExitError} from './non-zero-exit-error.js';

export {NonZeroExitError};

export interface Output {
stderr: string;
Expand Down Expand Up @@ -188,6 +191,10 @@ export class ExecProcess implements Result {
if (this._thrownError) {
throw this._thrownError;
}

if (this.exitCode !== 0 && this.exitCode !== undefined) {
throw new NonZeroExitError(this);
}
}

protected async _waitForOutput(): Promise<Output> {
Expand Down Expand Up @@ -224,6 +231,10 @@ export class ExecProcess implements Result {
throw this._thrownError;
}

if (this.exitCode !== 0 && this.exitCode !== undefined) {
throw new NonZeroExitError(this);
}

const result: Output = {
stderr,
stdout
Expand Down
18 changes: 18 additions & 0 deletions src/non-zero-exit-error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type {Result} from './main.js';

export class NonZeroExitError extends Error {
public readonly result: Result;

public get exitCode(): number | undefined {
if (this.result.exitCode !== null) {
return this.result.exitCode;
}
return undefined;
}

public constructor(result: Result) {
super(`Process exited with non-zero status (${result.exitCode})`);

this.result = result;
}
}
10 changes: 9 additions & 1 deletion src/test/main_test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {x} from '../main.js';
import {x, NonZeroExitError} from '../main.js';
import * as assert from 'node:assert/strict';
import {test} from 'node:test';
import os from 'node:os';
Expand All @@ -19,6 +19,14 @@ test('exec', async (t) => {
assert.equal(proc.exitCode, 0);
});

await t.test('non-zero exitCode throws', async () => {
const proc = x('node', ['-e', 'process.exit(1);']);
await assert.rejects(async () => {
await proc;
}, NonZeroExitError);
assert.equal(proc.exitCode, 1);
});

await t.test('async iterator gets correct output', async () => {
const proc = x('node', ['-e', "console.log('foo'); console.log('bar');"]);
const lines = [];
Expand Down

0 comments on commit 11449ee

Please sign in to comment.