diff --git a/index.js b/index.js index 4c2cbb1f0..e2941e1e2 100644 --- a/index.js +++ b/index.js @@ -109,9 +109,14 @@ function handleInput(spawned, input) { } } -function handleOutput(options, value) { - if (value && options.stripFinalNewline) { - value = stripFinalNewline(value); +function handleOutput(options, value, error) { + if (typeof value !== 'string' && !Buffer.isBuffer(value)) { + // When `execa.sync()` errors, we normalize it to '' to mimic `execa()` + return error === undefined ? undefined : ''; + } + + if (options.stripFinalNewline) { + return stripFinalNewline(value); } return value; @@ -423,8 +428,8 @@ module.exports.sync = (command, args, options) => { } const result = childProcess.spawnSync(parsed.command, parsed.args, parsed.options); - result.stdout = handleOutput(parsed.options, result.stdout); - result.stderr = handleOutput(parsed.options, result.stderr); + result.stdout = handleOutput(parsed.options, result.stdout, result.error); + result.stderr = handleOutput(parsed.options, result.stderr, result.error); if (result.error || result.status !== 0 || result.signal !== null) { const error = makeError(result, { diff --git a/readme.md b/readme.md index 7e573f179..ac1d5eb9a 100644 --- a/readme.md +++ b/readme.md @@ -107,8 +107,8 @@ try { command: 'wrong command', exitCode: 2, exitCodeName: 'ENOENT', - stdout: null, - stderr: null, + stdout: '', + stderr: '', failed: true, timedOut: false, isCanceled: false, diff --git a/test.js b/test.js index da64172d9..6544c2671 100644 --- a/test.js +++ b/test.js @@ -51,6 +51,40 @@ test('stdout/stderr/all available on errors', async t => { t.is(typeof error.all, 'string'); }); +test('stdout/stderr/all are undefined if ignored', async t => { + const {stdout, stderr, all} = await execa('noop', {stdio: 'ignore'}); + t.is(stdout, undefined); + t.is(stderr, undefined); + t.is(all, undefined); +}); + +test('stdout/stderr/all are undefined if ignored in sync mode', t => { + const {stdout, stderr, all} = execa.sync('noop', {stdio: 'ignore'}); + t.is(stdout, undefined); + t.is(stderr, undefined); + t.is(all, undefined); +}); + +const WRONG_COMMAND_STDERR = process.platform === 'win32' ? + '\'wrong\' is not recognized as an internal or external command,\r\noperable program or batch file.' : + ''; + +test('stdout/stderr/all on process errors', async t => { + const {stdout, stderr, all} = await t.throwsAsync(execa('wrong command')); + t.is(stdout, ''); + t.is(stderr, WRONG_COMMAND_STDERR); + t.is(all, WRONG_COMMAND_STDERR); +}); + +test('stdout/stderr/all on process errors, in sync mode', t => { + const {stdout, stderr, all} = t.throws(() => { + execa.sync('wrong command'); + }); + t.is(stdout, ''); + t.is(stderr, WRONG_COMMAND_STDERR); + t.is(all, undefined); +}); + test('pass `stdout` to a file descriptor', async t => { const file = tempfile('.txt'); await execa('fixtures/noop', ['foo bar'], {stdout: fs.openSync(file, 'w')});