Skip to content

Commit

Permalink
Distinguishing between error strings and error numbers (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky authored and sindresorhus committed Mar 10, 2019
1 parent ffc7ca9 commit 7d78db2
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 24 deletions.
26 changes: 16 additions & 10 deletions index.js
Expand Up @@ -126,17 +126,19 @@ function makeError(result, options) {
let {error} = result;
const {joinedCommand, timedOut, parsed: {options: {timeout}}} = options;

const [codeString, codeNumber] = getCode(result, code);
const [exitCodeName, exitCode] = getCode(result, code);

if (!(error instanceof Error)) {
const message = [joinedCommand, stderr, stdout].filter(Boolean).join('\n');
error = new Error(message);
}

const prefix = getErrorPrefix({timedOut, timeout, signal, codeString, codeNumber});
const prefix = getErrorPrefix({timedOut, timeout, signal, exitCodeName, exitCode});
error.message = `Command ${prefix}: ${error.message}`;

error.code = codeNumber || codeString;
error.code = exitCode || exitCodeName;
error.exitCode = exitCode;
error.exitCodeName = exitCodeName;
error.stdout = stdout;
error.stderr = stderr;
error.failed = true;
Expand All @@ -159,7 +161,7 @@ function getCode({error = {}}, code) {
return [];
}

function getErrorPrefix({timedOut, timeout, signal, codeString, codeNumber}) {
function getErrorPrefix({timedOut, timeout, signal, exitCodeName, exitCode}) {
if (timedOut) {
return `timed out after ${timeout} milliseconds`;
}
Expand All @@ -168,16 +170,16 @@ function getErrorPrefix({timedOut, timeout, signal, codeString, codeNumber}) {
return `was killed with ${signal}`;
}

if (codeString !== undefined && codeNumber !== undefined) {
return `failed with exit code ${codeNumber} (${codeString})`;
if (exitCodeName !== undefined && exitCode !== undefined) {
return `failed with exit code ${exitCode} (${exitCodeName})`;
}

if (codeString !== undefined) {
return `failed with exit code ${codeString}`;
if (exitCodeName !== undefined) {
return `failed with exit code ${exitCodeName}`;
}

if (codeNumber !== undefined) {
return `failed with exit code ${codeNumber}`;
if (exitCode !== undefined) {
return `failed with exit code ${exitCode}`;
}

return 'failed';
Expand Down Expand Up @@ -296,6 +298,8 @@ module.exports = (command, args, options) => {
stdout: handleOutput(parsed.options, result.stdout),
stderr: handleOutput(parsed.options, result.stderr),
code: 0,
exitCode: 0,
exitCodeName: 'SUCCESS',
failed: false,
killed: false,
signal: null,
Expand Down Expand Up @@ -362,6 +366,8 @@ module.exports.sync = (command, args, options) => {
stdout: handleOutput(parsed.options, result.stdout),
stderr: handleOutput(parsed.options, result.stderr),
code: 0,
exitCode: 0,
exitCodeName: 'SUCCESS',
failed: false,
signal: null,
cmd: joinedCommand,
Expand Down
22 changes: 14 additions & 8 deletions readme.md
Expand Up @@ -59,14 +59,17 @@ const execa = require('execa');
console.log(error);
/*
{
message: 'Command failed: /bin/sh -c exit 3'
killed: false,
message: 'Command failed with exit code 3 (ESRCH): exit 3',
code: 3,
signal: null,
cmd: '/bin/sh -c exit 3',
exitCode: 3,
exitCodeName: 'ESRCH',
stdout: '',
stderr: '',
timedOut: false
failed: true,
signal: null,
cmd: 'exit 3',
timedOut: false,
killed: false
}
*/
}
Expand All @@ -79,12 +82,15 @@ try {
console.log(error);
/*
{
message: 'Command failed: /bin/sh -c exit 3'
message: 'Command failed with exit code 3 (ESRCH): exit 3',
code: 3,
signal: null,
cmd: '/bin/sh -c exit 3',
exitCode: 3,
exitCodeName: 'ESRCH',
stdout: '',
stderr: '',
failed: true,
signal: null,
cmd: 'exit 3',
timedOut: false
}
*/
Expand Down
21 changes: 15 additions & 6 deletions test.js
Expand Up @@ -259,14 +259,22 @@ test('skip throwing when using reject option', async t => {
});

test('allow unknown exit code', async t => {
await t.throwsAsync(execa('exit', ['255']), {message: /exit code 255 \(Unknown system error -255\)/});
const {exitCode, exitCodeName} = await t.throwsAsync(execa('exit', ['255']), {message: /exit code 255 \(Unknown system error -255\)/});
t.is(exitCode, 255);
t.is(exitCodeName, 'Unknown system error -255');
});

test('execa() returns code and failed properties', async t => {
const {code, failed} = await execa('noop', ['foo']);
const error = await t.throwsAsync(execa('exit', ['2']), {code: 2, message: getExitRegExp('2')});
const {code, exitCode, exitCodeName, failed} = await execa('noop', ['foo']);
t.is(code, 0);
t.is(exitCode, 0);
t.is(exitCodeName, 'SUCCESS');
t.false(failed);

const error = await t.throwsAsync(execa('exit', ['2']), {code: 2, message: getExitRegExp('2')});
t.is(error.exitCode, 2);
const expectedName = process.platform === 'win32' ? 'Unknown system error -2' : 'ENOENT';
t.is(error.exitCodeName, expectedName);
t.true(error.failed);
});

Expand Down Expand Up @@ -361,7 +369,8 @@ test('result.signal is null if process failed, but was not killed', async t => {
});

async function code(t, num) {
await t.throwsAsync(execa('exit', [`${num}`]), {code: num, message: getExitRegExp(num)});
const error = await t.throwsAsync(execa('exit', [`${num}`]), {code: num, message: getExitRegExp(num)});
t.is(error.exitCode, num);
}

test('error.code is 2', code, 2);
Expand All @@ -372,7 +381,7 @@ test('timeout will kill the process early', async t => {
const error = await t.throwsAsync(execa('delay', ['60000', '0'], {timeout: 1500, message: TIMEOUT_REGEXP}));

t.true(error.timedOut);
t.not(error.code, 22);
t.not(error.exitCode, 22);
});

test('timeout will not kill the process early', async t => {
Expand Down Expand Up @@ -461,7 +470,7 @@ if (process.platform !== 'win32') {
await execa(`fast-exit-${process.platform}`, [], {input: 'data'});
t.pass();
} catch (error) {
t.is(error.code, 32);
t.is(error.exitCode, 32);
}
});
}
Expand Down

0 comments on commit 7d78db2

Please sign in to comment.