From 52934bce8aa35d366cc9112fd34178a8d5c3ca3c Mon Sep 17 00:00:00 2001 From: Ruben Anders Date: Mon, 31 Aug 2020 22:06:58 +0200 Subject: [PATCH] fix responses resolving more than one awaiter promise (#65) fix responses resolving more than one awaiter promise hopefully fixing #32 --- CHANGELOG.md | 2 ++ lib/await/await-response.ts | 8 ++++++-- lib/client/connection.ts | 9 +++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4d4a81a..a9ab8e59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unversioned +- Bugfix: Fixed a single server message resolving/rejecting more than one promise (e.g. cases where many messages were sent to the same channel, the first success/error response would resolve/reject all the waiting promises) (#32, #65) + ## v4.0.1 - Bugfix: Fixed exception if new unstable "flags" parsing failed because of an out-of-bounds index. diff --git a/lib/await/await-response.ts b/lib/await/await-response.ts index 27246227..a9d1d69c 100644 --- a/lib/await/await-response.ts +++ b/lib/await/await-response.ts @@ -85,7 +85,6 @@ export class ResponseAwaiter { }); this.subscribeTo("close", this.onConnectionClosed); - this.subscribeTo("message", this.onConnectionMessage); this.joinPendingResponsesQueue(); } @@ -199,12 +198,17 @@ export class ResponseAwaiter { } } - private onConnectionMessage(msg: IRCMessage): void { + // returns true if something matched, preventing "later" matchers from + // running against that message + public onConnectionMessage(msg: IRCMessage): boolean { if (this.config.failure(msg)) { this.reject(new MessageError(`Bad response message: ${msg.rawSource}`)); + return true; } else if (this.config.success(msg)) { this.resolve(msg); + return true; } + return false; } private subscribeTo( diff --git a/lib/client/connection.ts b/lib/client/connection.ts index b29fe597..fcb44f72 100644 --- a/lib/client/connection.ts +++ b/lib/client/connection.ts @@ -64,6 +64,15 @@ export class SingleConnection extends BaseClient { replyToServerPing(this); handleReconnectMessage(this); + + this.on("message", (msg) => { + for (const awaiter of this.pendingResponses) { + const stop = awaiter.onConnectionMessage(msg); + if (stop) { + break; + } + } + }); } public connect(): void {