Skip to content

Commit

Permalink
fix: propagate abort reason in derived signals
Browse files Browse the repository at this point in the history
Fixes #101
  • Loading branch information
connor4312 committed Nov 9, 2024
1 parent 975fc44 commit 9cd7d79
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 6 deletions.
8 changes: 4 additions & 4 deletions src/common/Event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,18 @@ export namespace Event {
}

/** Creates an Event that fires when the signal is aborted. */
export const onAbort = (signal: AbortSignal): { event: Event<void> } & IDisposable => {
const evt = new OneShotEvent<void>();
export const onAbort = (signal: AbortSignal): { event: Event<unknown> } & IDisposable => {
const evt = new OneShotEvent<unknown>();
if (signal.aborted) {
evt.emit();
evt.emit(signal.reason);
return { event: evt.addListener, dispose: () => {} };
}

const dispose = () => (signal as any).removeEventListener('abort', l);

// @types/node is currently missing the event types on AbortSignal
const l = () => {
evt.emit();
evt.emit(signal.reason);
dispose();
};

Expand Down
21 changes: 21 additions & 0 deletions src/common/abort.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { expect } from 'chai';
import { deriveAbortController } from './abort';

describe('deriveAbortController', () => {
it('should return an aborted AbortController when the provided signal is already aborted', () => {
const parentCtrl = new AbortController();
parentCtrl.abort(new Error('asdf'));
const { ctrl } = deriveAbortController(parentCtrl.signal);
expect(ctrl.signal.aborted).to.be.true;
expect(ctrl.signal.reason).to.equal(parentCtrl.signal.reason);
});

it('should abort the new AbortController when the provided signal aborts', () => {
const parentCtrl = new AbortController();
const { ctrl } = deriveAbortController(parentCtrl.signal);
expect(ctrl.signal.aborted).to.be.false;
parentCtrl.abort(new Error('asdf'));
expect(ctrl.signal.aborted).to.be.true;
expect(ctrl.signal.reason).to.equal(parentCtrl.signal.reason);
});
});
4 changes: 2 additions & 2 deletions src/common/abort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ export const deriveAbortController = (
}

if (signal.aborted) {
ctrl.abort();
ctrl.abort(signal.reason);
} else {
const abortEvt = onAbort(signal);
abortEvt.event(() => ctrl.abort());
abortEvt.event(reason => ctrl.abort(reason));
dispose = abortEvt.dispose;
}

Expand Down

0 comments on commit 9cd7d79

Please sign in to comment.