From eccac95011dcb6a4a1f7373a60b98252550ead50 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 5 Oct 2026 16:02:22 -0700 Subject: [PATCH] Fix a deadlock when async compiler fails to start We weren't properly listening to the close event of the message stream. Closes #448 --- lib/src/dispatcher.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/src/dispatcher.ts b/lib/src/dispatcher.ts index 784c1068..5bfc95db 100644 --- a/lib/src/dispatcher.ts +++ b/lib/src/dispatcher.ts @@ -121,7 +121,10 @@ export class Dispatcher { callback: ResponseCallback, ): void { // Call the callback but unsubscribe first + let calledCallback = false; const callback_: ResponseCallback = (err, response) => { + if (calledCallback) return; + calledCallback = true; this.unsubscribe(); return callback(err, response); }; @@ -136,7 +139,20 @@ export class Dispatcher { filter(message => message.message.case === 'compileResponse'), map(message => message.message.value as OutboundResponse), ) - .subscribe({next: response => callback_(null, response)}); + .subscribe({ + next: response => callback_(null, response), + complete: () => + // Wrap this in a setTimeout so that, if it's racing with + // `this.error$`, the error message wins. + setTimeout( + () => + callback_( + new Error('Dispatcher closed before compilation completed'), + undefined, + ), + 0, + ), + }); this.error$.subscribe({ error: error => callback_(error, undefined),