Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add unhandled error case
Browse files Browse the repository at this point in the history
Kikobeats committed Jun 18, 2024

Unverified

No user is associated with the committer email.
1 parent 7659647 commit f035325
Showing 3 changed files with 42 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 80
max_line_length = 100
indent_brace_style = 1TBS
spaces_around_operators = true
quote_type = auto
49 changes: 24 additions & 25 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -3,16 +3,30 @@
const { spawn } = require('child_process')
const { EOL } = require('os')

const EE_PROPS = Object.getOwnPropertyNames(
require('events').EventEmitter.prototype
)
const EE_PROPS = Object.getOwnPropertyNames(require('events').EventEmitter.prototype)
.filter(name => !name.startsWith('_'))
.concat(['kill', 'ref', 'unref'])

const eos = (stream, listener, buffer = []) =>
stream[listener]
? stream[listener].on('data', data => buffer.push(data)) && buffer
: buffer
stream[listener] ? stream[listener].on('data', data => buffer.push(data)) && buffer : buffer

const createChildProcessError = ({ cmd, cmdArgs, exitCode, stderr, childProcess }) => {
const command = `${cmd} ${cmdArgs.join(' ')}`
let message = `The command spawned as:${EOL}${EOL}`
message += ` ${command}${EOL}${EOL}`
message += `exited with \`{ code: ${exitCode} }\` and the following trace:${EOL}${EOL}`
message += String(stderr)
.split(EOL)
.map(line => ` ${line}`)
.join(EOL)
const error = new Error(message)
error.command = command
error.name = 'ChildProcessError'
Object.keys(childProcess).forEach(key => {
error[key] = childProcess[key]
})
return error
}

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

@@ -42,30 +56,15 @@ const extend = defaults => (input, args, options) => {
get: parse(stdout, opts)
})
Object.defineProperty(childProcess, 'stderr', { get: parse(stderr) })
if (exitCode === 0) return resolve(childProcess)
const command = `${cmd} ${cmdArgs.join(' ')}`
let message = `The command spawned as:${EOL}${EOL}`
message += ` ${command}${EOL}${EOL}`
message += `exited with \`{ code: ${exitCode} }\` and the following trace:${EOL}${EOL}`
message += String(stderr)
.split(EOL)
.map(line => ` ${line}`)
.join(EOL)
const error = new Error(message)
error.command = command
error.name = 'ChildProcessError'
Object.keys(childProcess).forEach(key => {
error[key] = childProcess[key]
})
reject(error)
return exitCode === 0
? resolve(childProcess)
: reject(createChildProcessError({ cmd, cmdArgs, exitCode, stderr, childProcess }))
})
})

const subprocess = Object.assign(promise, childProcess)
if (childProcess) {
EE_PROPS.forEach(
name => (subprocess[name] = childProcess[name].bind(childProcess))
)
EE_PROPS.forEach(name => (subprocess[name] = childProcess[name].bind(childProcess)))
}
return subprocess
}
26 changes: 17 additions & 9 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict'

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

test.skip('control process lifecycle', async t => {
t.plan(2)
try {
const subprocess = $('sleep 100')
await setTimeout(500)
subprocess.kill('SIGKILL')
await subprocess
} catch (error) {
t.is(error.killed, true)
t.is(error.signalCode, 'SIGKILL')
}
})

test.serial('run a command', async t => {
{
const result = await $('echo hello world')
@@ -39,9 +53,7 @@ test.serial('run a command', async t => {
t.is(result.spawnfile, SHELL)
t.deepEqual(
result.spawnargs,
isWindows
? ['hello world', '/d', '/s', '/c', '"echo $0"']
: ['hello world', '-c', 'echo $0']
isWindows ? ['hello world', '/d', '/s', '/c', '"echo $0"'] : ['hello world', '-c', 'echo $0']
)
}
{
@@ -61,9 +73,7 @@ test.serial('run a command', async t => {
t.is(result.spawnfile, SHELL)
t.deepEqual(
result.spawnargs,
isWindows
? ['world', '/d', '/s', '/c', '"echo hello $0"']
: ['world', '-c', 'echo hello $0']
isWindows ? ['world', '/d', '/s', '/c', '"echo hello $0"'] : ['world', '-c', 'echo hello $0']
)
}
})
@@ -100,9 +110,7 @@ test('output is child_process', async t => {
})

test('$.json', async t => {
const { stdout } = await require('..').json(
'curl https://geolocation.microlink.io'
)
const { stdout } = await require('..').json('curl https://geolocation.microlink.io')
t.true(!!stdout.ip.address)
})

0 comments on commit f035325

Please sign in to comment.