From 4c1a3fe9465c0b690aa3ae29f79a39fbaa991a61 Mon Sep 17 00:00:00 2001 From: Leo Bernard Date: Fri, 3 May 2024 11:00:47 +0200 Subject: [PATCH] :bug: Fix some pending requests never resolving when Live disconnects, immediately reject pending requests when Live sends a realtime disconnect event --- src/index.ts | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/index.ts b/src/index.ts index 304d826..b0b6770 100644 --- a/src/index.ts +++ b/src/index.ts @@ -60,6 +60,12 @@ export class TimeoutError extends Error { } } +export class DisconnectError extends Error { + constructor(public message: string, public payload: Command) { + super(message); + } +} + export interface AbletonOptions { /** * Name of the file containing the port of the Remote Script. This @@ -177,8 +183,14 @@ export class Ableton extends EventEmitter implements ConnectionEventEmitter { if (this._isConnected) { this._isConnected = false; this.eventListeners.clear(); - this.msgMap.forEach((msg) => msg.clearTimeout()); - this.msgMap.clear(); + + // If the disconnect is caused by missed heartbeats, keep + // pending requests. Live might just be temporarily hanging. + if (type === "realtime") { + this.msgMap.forEach((msg) => msg.clearTimeout()); + this.msgMap.clear(); + } + this.logger?.info("Live disconnected", { type }); this.emit("disconnect", type); } @@ -462,19 +474,13 @@ export class Ableton extends EventEmitter implements ConnectionEventEmitter { }; const msg = JSON.stringify(payload); const timeout = this.options?.commandTimeoutMs ?? 2000; + const arg = truncate(JSON.stringify(command.args), { length: 100 }); + const cls = command.nsid ? `${command.ns}(${command.nsid})` : command.ns; const timeoutId = setTimeout(() => { - const arg = truncate(JSON.stringify(command.args), { length: 100 }); - const cls = command.nsid - ? `${command.ns}(${command.nsid})` - : command.ns; rej( new TimeoutError( - [ - `The command ${cls}.${command.name}(${arg}) timed out after ${timeout} ms.`, - `Please make sure that Ableton is running and that you have the latest`, - `version of AbletonJS' MIDI script installed and renamed to "AbletonJS".`, - ].join(" "), + `The command ${cls}.${command.name}(${arg}) timed out after ${timeout} ms.`, payload, ), ); @@ -499,6 +505,12 @@ export class Ableton extends EventEmitter implements ConnectionEventEmitter { rej, clearTimeout: () => { clearTimeout(timeoutId); + rej( + new DisconnectError( + `Live disconnected before being able to respond to ${cls}.${command.name}(${arg})`, + payload, + ), + ); }, });