Skip to content

Commit

Permalink
fix: reject with error from parent context on close (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukekarrys authored Apr 15, 2024
1 parent 16b3641 commit 4912015
Showing 1 changed file with 39 additions and 38 deletions.
77 changes: 39 additions & 38 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,54 +12,55 @@ const promiseSpawn = (cmd, args, opts = {}, extra = {}) => {
return spawnWithShell(cmd, args, opts, extra)
}

let proc
let resolve, reject
const promise = new Promise((_resolve, _reject) => {
resolve = _resolve
reject = _reject
})

const p = new Promise((res, rej) => {
proc = spawn(cmd, args, opts)
// Create error here so we have a more useful stack trace when rejecting
const closeError = new Error('command failed')

const stdout = []
const stderr = []
const stdout = []
const stderr = []

const reject = er => rej(Object.assign(er, {
cmd,
args,
...stdioResult(stdout, stderr, opts),
...extra,
}))
const getResult = (result) => ({
cmd,
args,
...result,
...stdioResult(stdout, stderr, opts),
...extra,
})
const rejectWithOpts = (er, erOpts) => {
const resultError = getResult(erOpts)
reject(Object.assign(er, resultError))
}

proc.on('error', reject)
const proc = spawn(cmd, args, opts)
promise.stdin = proc.stdin
promise.process = proc

if (proc.stdout) {
proc.stdout.on('data', c => stdout.push(c)).on('error', reject)
proc.stdout.on('error', er => reject(er))
}
proc.on('error', rejectWithOpts)

if (proc.stderr) {
proc.stderr.on('data', c => stderr.push(c)).on('error', reject)
proc.stderr.on('error', er => reject(er))
}
if (proc.stdout) {
proc.stdout.on('data', c => stdout.push(c))
proc.stdout.on('error', rejectWithOpts)
}

proc.on('close', (code, signal) => {
const result = {
cmd,
args,
code,
signal,
...stdioResult(stdout, stderr, opts),
...extra,
}
if (proc.stderr) {
proc.stderr.on('data', c => stderr.push(c))
proc.stderr.on('error', rejectWithOpts)
}

if (code || signal) {
rej(Object.assign(new Error('command failed'), result))
} else {
res(result)
}
})
proc.on('close', (code, signal) => {
if (code || signal) {
rejectWithOpts(closeError, { code, signal })
} else {
resolve(getResult({ code, signal }))
}
})

p.stdin = proc.stdin
p.process = proc
return p
return promise
}

const spawnWithShell = (cmd, args, opts, extra) => {
Expand Down

0 comments on commit 4912015

Please sign in to comment.