You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-10 11:43:01 +03:00
fix #1636 - fix WatchError
This commit is contained in:
@@ -2,9 +2,10 @@ import { strict as assert } from 'assert';
|
|||||||
import { once } from 'events';
|
import { once } from 'events';
|
||||||
import { itWithClient, TEST_REDIS_SERVERS, TestRedisServers, waitTillBeenCalled, isRedisVersionGreaterThan } from './test-utils';
|
import { itWithClient, TEST_REDIS_SERVERS, TestRedisServers, waitTillBeenCalled, isRedisVersionGreaterThan } from './test-utils';
|
||||||
import RedisClient from './client';
|
import RedisClient from './client';
|
||||||
import { AbortError } from './errors';
|
import { AbortError, WatchError } from './errors';
|
||||||
import { defineScript } from './lua-script';
|
import { defineScript } from './lua-script';
|
||||||
import { spy } from 'sinon';
|
import { spy } from 'sinon';
|
||||||
|
import { commandOptions } from './command-options';
|
||||||
|
|
||||||
export const SQUARE_SCRIPT = defineScript({
|
export const SQUARE_SCRIPT = defineScript({
|
||||||
NUMBER_OF_KEYS: 0,
|
NUMBER_OF_KEYS: 0,
|
||||||
@@ -222,7 +223,7 @@ describe('Client', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('multi', () => {
|
describe.only('multi', () => {
|
||||||
itWithClient(TestRedisServers.OPEN, 'simple', async client => {
|
itWithClient(TestRedisServers.OPEN, 'simple', async client => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
await client.multi()
|
await client.multi()
|
||||||
@@ -268,6 +269,25 @@ describe('Client', () => {
|
|||||||
await client.disconnect();
|
await client.disconnect();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
itWithClient(TestRedisServers.OPEN, 'WatchError', async client => {
|
||||||
|
await client.watch('key');
|
||||||
|
|
||||||
|
await client.set(
|
||||||
|
RedisClient.commandOptions({
|
||||||
|
isolated: true
|
||||||
|
}),
|
||||||
|
'key',
|
||||||
|
'1'
|
||||||
|
);
|
||||||
|
|
||||||
|
await assert.rejects(
|
||||||
|
client.multi()
|
||||||
|
.decr('key')
|
||||||
|
.exec(),
|
||||||
|
WatchError
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('scripts', async () => {
|
it('scripts', async () => {
|
||||||
|
@@ -47,7 +47,7 @@ describe('Multi Command', () => {
|
|||||||
|
|
||||||
it('WatchError', async () => {
|
it('WatchError', async () => {
|
||||||
assert.rejects(
|
assert.rejects(
|
||||||
RedisMultiCommand.create(() => Promise.resolve(null)).exec(),
|
RedisMultiCommand.create(() => Promise.resolve([null])).exec(),
|
||||||
WatchError
|
WatchError
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@@ -29,7 +29,7 @@ export interface MultiQueuedCommand {
|
|||||||
transformReply?: RedisCommand['transformReply'];
|
transformReply?: RedisCommand['transformReply'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RedisMultiExecutor = (queue: Array<MultiQueuedCommand>, chainId?: symbol) => Promise<null | Array<RedisReply>>;
|
export type RedisMultiExecutor = (queue: Array<MultiQueuedCommand>, chainId?: symbol) => Promise<Array<RedisReply>>;
|
||||||
|
|
||||||
export default class RedisMultiCommand<M extends RedisModules = RedisModules, S extends RedisLuaScripts = RedisLuaScripts> {
|
export default class RedisMultiCommand<M extends RedisModules = RedisModules, S extends RedisLuaScripts = RedisLuaScripts> {
|
||||||
static commandsExecutor(this: RedisMultiCommand, command: RedisCommand, args: Array<unknown>): RedisMultiCommand {
|
static commandsExecutor(this: RedisMultiCommand, command: RedisCommand, args: Array<unknown>): RedisMultiCommand {
|
||||||
@@ -169,22 +169,22 @@ export default class RedisMultiCommand<M extends RedisModules = RedisModules, S
|
|||||||
}
|
}
|
||||||
|
|
||||||
const queue = this.#queue.splice(0),
|
const queue = this.#queue.splice(0),
|
||||||
rawReplies = this.#handleNullReply(
|
rawReplies = await this.#executor([
|
||||||
await this.#executor([
|
{
|
||||||
{
|
encodedCommand: encodeCommand(['MULTI'])
|
||||||
encodedCommand: encodeCommand(['MULTI'])
|
},
|
||||||
},
|
...queue,
|
||||||
...queue,
|
{
|
||||||
{
|
encodedCommand: encodeCommand(['EXEC'])
|
||||||
encodedCommand: encodeCommand(['EXEC'])
|
}
|
||||||
}
|
], Symbol('[RedisMultiCommand] Chain ID')),
|
||||||
], Symbol('[RedisMultiCommand] Chain ID'))
|
execReply = rawReplies[rawReplies.length - 1] as (null | Array<RedisReply>);
|
||||||
);
|
|
||||||
|
|
||||||
return this.#transformReplies(
|
if (execReply === null) {
|
||||||
rawReplies[rawReplies.length - 1] as Array<RedisReply>,
|
throw new WatchError();
|
||||||
queue
|
}
|
||||||
);
|
|
||||||
|
return this.#transformReplies(execReply, queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
async execAsPipeline(): Promise<Array<RedisReply>> {
|
async execAsPipeline(): Promise<Array<RedisReply>> {
|
||||||
@@ -194,19 +194,11 @@ export default class RedisMultiCommand<M extends RedisModules = RedisModules, S
|
|||||||
|
|
||||||
const queue = this.#queue.splice(0);
|
const queue = this.#queue.splice(0);
|
||||||
return this.#transformReplies(
|
return this.#transformReplies(
|
||||||
this.#handleNullReply(await this.#executor(queue)),
|
await this.#executor(queue),
|
||||||
queue
|
queue
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#handleNullReply<T>(reply: null | T): T {
|
|
||||||
if (reply === null) {
|
|
||||||
throw new WatchError();
|
|
||||||
}
|
|
||||||
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
#transformReplies(rawReplies: Array<RedisReply>, queue: Array<MultiQueuedCommand>): Array<RedisReply> {
|
#transformReplies(rawReplies: Array<RedisReply>, queue: Array<MultiQueuedCommand>): Array<RedisReply> {
|
||||||
return rawReplies.map((reply, i) => {
|
return rawReplies.map((reply, i) => {
|
||||||
const { transformReply, preservedArguments } = queue[i];
|
const { transformReply, preservedArguments } = queue[i];
|
||||||
|
Reference in New Issue
Block a user