diff --git a/packages/gateway/src/Shard.ts b/packages/gateway/src/Shard.ts index 267b5f3ac..afa8e996e 100644 --- a/packages/gateway/src/Shard.ts +++ b/packages/gateway/src/Shard.ts @@ -128,15 +128,27 @@ export class DiscordenoShard { /** Close the socket connection to discord if present. */ async close(code: number, reason: string): Promise { - if (this.socket?.readyState !== NodeWebSocket.OPEN) return + this.logger.debug(`[Shard] Request for Shard #${this.id} to close the socket.`) - this.socket?.close(code, reason) + if (this.socket?.readyState !== NodeWebSocket.OPEN) { + this.logger.debug(`[Shard] Shard #${this.id}'s ready state is ${this.socket?.readyState}, Unable to close.`) + return + } - // We need to wait for the socket to be fully closed, otherwise there'll be race condition issues if we try to connect again, resulting in unexpected behavior. - await new Promise((resolve) => { + // This has to be created before the actual call to socket.close as for example Bun calls socket.onclose immediately on the .close() call instead of waiting for the connection to end + const promise = new Promise((resolve) => { this.resolveAfterClose = resolve }) + this.socket.close(code, reason) + + this.logger.debug(`[Shard] Waiting for Shard #${this.id} to close the socket.`) + + // We need to wait for the socket to be fully closed, otherwise there'll be race condition issues if we try to connect again, resulting in unexpected behavior. + await promise + + this.logger.debug(`[Shard] Shard #${this.id} closed the socket.`) + // Reset the resolveAfterClose function after it has been resolved. this.resolveAfterClose = undefined } @@ -583,6 +595,7 @@ export class DiscordenoShard { break } case GatewayOpcodes.Reconnect: { + this.logger.debug(`[Shard] Received a Reconnect for Shard #${this.id}`) this.events.requestedReconnect?.(this) await this.resume()