From 7e1414efcfc29f9ff142efa5622f3f7b1234c819 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 8 Nov 2024 22:21:57 -0800 Subject: [PATCH] fix: propagate abort reason in derived signals Fixes #101 --- src/common/Event.ts | 8 ++++---- src/common/abort.test.ts | 21 +++++++++++++++++++++ src/common/abort.ts | 4 ++-- 3 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 src/common/abort.test.ts diff --git a/src/common/Event.ts b/src/common/Event.ts index 59dddb0..1f84c7e 100644 --- a/src/common/Event.ts +++ b/src/common/Event.ts @@ -79,10 +79,10 @@ export namespace Event { } /** Creates an Event that fires when the signal is aborted. */ -export const onAbort = (signal: AbortSignal): { event: Event } & IDisposable => { - const evt = new OneShotEvent(); +export const onAbort = (signal: AbortSignal): { event: Event } & IDisposable => { + const evt = new OneShotEvent(); if (signal.aborted) { - evt.emit(); + evt.emit(signal.reason); return { event: evt.addListener, dispose: () => {} }; } @@ -90,7 +90,7 @@ export const onAbort = (signal: AbortSignal): { event: Event } & IDisposab // @types/node is currently missing the event types on AbortSignal const l = () => { - evt.emit(); + evt.emit(signal.reason); dispose(); }; diff --git a/src/common/abort.test.ts b/src/common/abort.test.ts new file mode 100644 index 0000000..d8b5f78 --- /dev/null +++ b/src/common/abort.test.ts @@ -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); + }); +}); diff --git a/src/common/abort.ts b/src/common/abort.ts index 264c319..9862997 100644 --- a/src/common/abort.ts +++ b/src/common/abort.ts @@ -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; }