Skip to content

Commit 352e151

Browse files
authored
test: add unhandled error case (#14)
1 parent 7659647 commit 352e151

File tree

3 files changed

+42
-35
lines changed

3 files changed

+42
-35
lines changed

.editorconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ end_of_line = lf
99
charset = utf-8
1010
trim_trailing_whitespace = true
1111
insert_final_newline = true
12-
max_line_length = 80
12+
max_line_length = 100
1313
indent_brace_style = 1TBS
1414
spaces_around_operators = true
1515
quote_type = auto

src/index.js

+24-25
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,30 @@
33
const { spawn } = require('child_process')
44
const { EOL } = require('os')
55

6-
const EE_PROPS = Object.getOwnPropertyNames(
7-
require('events').EventEmitter.prototype
8-
)
6+
const EE_PROPS = Object.getOwnPropertyNames(require('events').EventEmitter.prototype)
97
.filter(name => !name.startsWith('_'))
108
.concat(['kill', 'ref', 'unref'])
119

1210
const eos = (stream, listener, buffer = []) =>
13-
stream[listener]
14-
? stream[listener].on('data', data => buffer.push(data)) && buffer
15-
: buffer
11+
stream[listener] ? stream[listener].on('data', data => buffer.push(data)) && buffer : buffer
12+
13+
const createChildProcessError = ({ cmd, cmdArgs, exitCode, stderr, childProcess }) => {
14+
const command = `${cmd} ${cmdArgs.join(' ')}`
15+
let message = `The command spawned as:${EOL}${EOL}`
16+
message += ` ${command}${EOL}${EOL}`
17+
message += `exited with \`{ code: ${exitCode} }\` and the following trace:${EOL}${EOL}`
18+
message += String(stderr)
19+
.split(EOL)
20+
.map(line => ` ${line}`)
21+
.join(EOL)
22+
const error = new Error(message)
23+
error.command = command
24+
error.name = 'ChildProcessError'
25+
Object.keys(childProcess).forEach(key => {
26+
error[key] = childProcess[key]
27+
})
28+
return error
29+
}
1630

1731
const clean = str => str.trim().replace(/\n$/, '')
1832

@@ -42,30 +56,15 @@ const extend = defaults => (input, args, options) => {
4256
get: parse(stdout, opts)
4357
})
4458
Object.defineProperty(childProcess, 'stderr', { get: parse(stderr) })
45-
if (exitCode === 0) return resolve(childProcess)
46-
const command = `${cmd} ${cmdArgs.join(' ')}`
47-
let message = `The command spawned as:${EOL}${EOL}`
48-
message += ` ${command}${EOL}${EOL}`
49-
message += `exited with \`{ code: ${exitCode} }\` and the following trace:${EOL}${EOL}`
50-
message += String(stderr)
51-
.split(EOL)
52-
.map(line => ` ${line}`)
53-
.join(EOL)
54-
const error = new Error(message)
55-
error.command = command
56-
error.name = 'ChildProcessError'
57-
Object.keys(childProcess).forEach(key => {
58-
error[key] = childProcess[key]
59-
})
60-
reject(error)
59+
return exitCode === 0
60+
? resolve(childProcess)
61+
: reject(createChildProcessError({ cmd, cmdArgs, exitCode, stderr, childProcess }))
6162
})
6263
})
6364

6465
const subprocess = Object.assign(promise, childProcess)
6566
if (childProcess) {
66-
EE_PROPS.forEach(
67-
name => (subprocess[name] = childProcess[name].bind(childProcess))
68-
)
67+
EE_PROPS.forEach(name => (subprocess[name] = childProcess[name].bind(childProcess)))
6968
}
7069
return subprocess
7170
}

test/index.js

+17-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict'
22

3+
const { setTimeout } = require('timers/promises')
34
const { execSync } = require('child_process')
45
const { Writable } = require('stream')
56
const { EOL } = require('os')
@@ -21,6 +22,19 @@ test('meaningful errors', async t => {
2122
t.is(error.killed, false)
2223
})
2324

25+
test.skip('control process lifecycle', async t => {
26+
t.plan(2)
27+
try {
28+
const subprocess = $('sleep 100')
29+
await setTimeout(500)
30+
subprocess.kill('SIGKILL')
31+
await subprocess
32+
} catch (error) {
33+
t.is(error.killed, true)
34+
t.is(error.signalCode, 'SIGKILL')
35+
}
36+
})
37+
2438
test.serial('run a command', async t => {
2539
{
2640
const result = await $('echo hello world')
@@ -39,9 +53,7 @@ test.serial('run a command', async t => {
3953
t.is(result.spawnfile, SHELL)
4054
t.deepEqual(
4155
result.spawnargs,
42-
isWindows
43-
? ['hello world', '/d', '/s', '/c', '"echo $0"']
44-
: ['hello world', '-c', 'echo $0']
56+
isWindows ? ['hello world', '/d', '/s', '/c', '"echo $0"'] : ['hello world', '-c', 'echo $0']
4557
)
4658
}
4759
{
@@ -61,9 +73,7 @@ test.serial('run a command', async t => {
6173
t.is(result.spawnfile, SHELL)
6274
t.deepEqual(
6375
result.spawnargs,
64-
isWindows
65-
? ['world', '/d', '/s', '/c', '"echo hello $0"']
66-
: ['world', '-c', 'echo hello $0']
76+
isWindows ? ['world', '/d', '/s', '/c', '"echo hello $0"'] : ['world', '-c', 'echo hello $0']
6777
)
6878
}
6979
})
@@ -100,9 +110,7 @@ test('output is child_process', async t => {
100110
})
101111

102112
test('$.json', async t => {
103-
const { stdout } = await require('..').json(
104-
'curl https://geolocation.microlink.io'
105-
)
113+
const { stdout } = await require('..').json('curl https://geolocation.microlink.io')
106114
t.true(!!stdout.ip.address)
107115
})
108116

0 commit comments

Comments
 (0)