From e5532706cfece84462c5aa539fa11b402ff4d9e1 Mon Sep 17 00:00:00 2001 From: Leibale Eidelman Date: Wed, 16 Nov 2022 16:27:36 -0500 Subject: [PATCH] fix #2205 - reject commands in connect phase when `disableOfflineQueue` is `true` --- packages/client/lib/client/index.spec.ts | 18 +++++++++++++++++- packages/client/lib/client/index.ts | 10 +++++----- packages/client/lib/errors.ts | 6 ++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/packages/client/lib/client/index.spec.ts b/packages/client/lib/client/index.spec.ts index 6294e155a44..4eee7076295 100644 --- a/packages/client/lib/client/index.spec.ts +++ b/packages/client/lib/client/index.spec.ts @@ -3,7 +3,7 @@ import testUtils, { GLOBAL, waitTillBeenCalled } from '../test-utils'; import RedisClient, { RedisClientType } from '.'; import { RedisClientMultiCommandType } from './multi-command'; import { RedisCommandArguments, RedisCommandRawReply, RedisModules, RedisFunctions, RedisScripts } from '../commands'; -import { AbortError, ClientClosedError, ConnectionTimeoutError, DisconnectsClientError, SocketClosedUnexpectedlyError, WatchError } from '../errors'; +import { AbortError, ClientClosedError, ClientOfflineError, ConnectionTimeoutError, DisconnectsClientError, SocketClosedUnexpectedlyError, WatchError } from '../errors'; import { defineScript } from '../lua-script'; import { spy } from 'sinon'; import { once } from 'events'; @@ -874,4 +874,20 @@ describe('Client', () => { pingInterval: 1 } }); + + testUtils.testWithClient('should reject commands in connect phase when `disableOfflineQueue`', async client => { + const connectPromise = client.connect(); + await assert.rejects( + client.ping(), + ClientOfflineError + ); + await connectPromise; + await client.disconnect(); + }, { + ...GLOBAL.SERVERS.OPEN, + clientOptions: { + disableOfflineQueue: true + }, + disableClientSetup: true + }); }); diff --git a/packages/client/lib/client/index.ts b/packages/client/lib/client/index.ts index e6f1fef10e5..c4259f72b82 100644 --- a/packages/client/lib/client/index.ts +++ b/packages/client/lib/client/index.ts @@ -11,7 +11,7 @@ import { ScanCommandOptions } from '../commands/SCAN'; import { HScanTuple } from '../commands/HSCAN'; import { attachCommands, attachExtensions, fCallArguments, transformCommandArguments, transformCommandReply, transformLegacyCommandArguments } from '../commander'; import { Pool, Options as PoolOptions, createPool } from 'generic-pool'; -import { ClientClosedError, DisconnectsClientError } from '../errors'; +import { ClientClosedError, ClientOfflineError, DisconnectsClientError } from '../errors'; import { URL } from 'url'; import { TcpSocketConnectOpts } from 'net'; @@ -405,16 +405,16 @@ export default class RedisClient< ): Promise { if (!this.#socket.isOpen) { return Promise.reject(new ClientClosedError()); - } - - if (options?.isolated) { + } else if (options?.isolated) { return this.executeIsolated(isolatedClient => isolatedClient.sendCommand(args, { ...options, isolated: false }) ); - } + } else if (!this.#socket.isReady && this.#options?.disableOfflineQueue) { + return Promise.reject(new ClientOfflineError()); + } const promise = this.#queue.addCommand(args, options); this.#tick(); diff --git a/packages/client/lib/errors.ts b/packages/client/lib/errors.ts index 3f3b9624987..30709703153 100644 --- a/packages/client/lib/errors.ts +++ b/packages/client/lib/errors.ts @@ -22,6 +22,12 @@ export class ClientClosedError extends Error { } } +export class ClientOfflineError extends Error { + constructor() { + super('The client is offline'); + } +} + export class DisconnectsClientError extends Error { constructor() { super('Disconnects client');