Skip to content

Commit

Permalink
feat: expose abortion signal from ProcessPromise
Browse files Browse the repository at this point in the history
  • Loading branch information
antongolub committed May 21, 2024
1 parent 99486e5 commit a73924d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
this._from = from
this._resolve = resolve
this._reject = reject
this._snapshot = { ...options }
this._snapshot = { ac: new AbortController(), ...options }
}

run(): ProcessPromise {
Expand Down Expand Up @@ -448,12 +448,19 @@ export class ProcessPromise extends Promise<ProcessOutput> {
}

abort(reason?: string) {
if (this.signal !== this._snapshot.ac?.signal)
throw new Error('The signal is controlled by another process.')

if (!this.child)
throw new Error('Trying to abort a process without creating one.')

this._zurk?.ac.abort(reason)
}

get signal() {
return this._snapshot.signal || this._snapshot.ac?.signal
}

async kill(signal = 'SIGTERM'): Promise<void> {
if (!this.child)
throw new Error('Trying to kill a process without creating one.')
Expand Down
39 changes: 39 additions & 0 deletions test/core.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,45 @@ describe('core', () => {
assert.match(message, /The operation was aborted/)
}
})

test('exposes `signal` property', async () => {
const ac = new AbortController()
const p = $({ ac, detached: true })`echo test`

assert.equal(p.signal, ac.signal)
await p
})

test('throws if the signal was previously aborted', async () => {
const ac = new AbortController()
const { signal } = ac
ac.abort('reason')

try {
await $({ signal, detached: true })`sleep 999`
} catch ({ message }) {
assert.match(message, /The operation was aborted/)
}
})

test('throws if the signal is controlled by another process', async () => {
const ac = new AbortController()
const { signal } = ac
const p = $({ signal })`sleep 999`

try {
p.abort()
} catch ({ message }) {
assert.match(message, /The signal is controlled by another process./)
}

try {
ac.abort()
await p
} catch ({ message }) {
assert.match(message, /The operation was aborted/)
}
})
})

describe('kill()', () => {
Expand Down

0 comments on commit a73924d

Please sign in to comment.