Skip to content

Unhandled promise when client pool receives multiple errors #3034

@levavakian

Description

@levavakian

Description

When running a command via the RedisClientPool, only the first error will correctly be emitted when awaiting on the result. Subsequent errors become uncaught promises that percolate up to the Node unhandled promise hook.

Here is the code to reproduce it:

import { RedisClientPoolType, createClientPool } from "redis"; async function test_group_op( redisClient: RedisClientPoolType, streamKey: string, consumerGroup: string, ) { try { const result = await redisClient.execute(async (client) => { return await client.xGroupCreate(streamKey, consumerGroup, "0", { MKSTREAM: true, }); }); console.log("TRY BLOCK - result", result); } catch (error) { console.log(`[${Date.now()}] CATCH BLOCK - error caught:`, error); console.log(`[${Date.now()}] CATCH BLOCK - error type:`, typeof error); console.log(`[${Date.now()}] CATCH BLOCK - error constructor:`, error?.constructor?.name); console.log(`[${Date.now()}] CATCH BLOCK - BUSYGROUP error handled`); } } async function main() { const WORK_STREAM_KEY = "stream-1"; const CONSUMER_GROUP = "group-1"; let redisClient: RedisClientPoolType | null = null; redisClient = createClientPool({ url: process.env.REDIS_URL!, }, { maximum: 100, minimum: 10 }); redisClient.on("error", (error) => { console.log("Redis client error", error); }); await redisClient.connect(); for (let i = 0; i < 3; i++) { console.log("Attempting group op", i); try { await test_group_op(redisClient, WORK_STREAM_KEY, CONSUMER_GROUP); } catch (error) { console.log("Group op error", error, "on attempt", i); } } await redisClient.close(); } process.on('unhandledRejection', (reason: any, promise: Promise<any>) => { console.error(`[${Date.now()}] UNHANDLED REJECTION at:`, promise); console.error(`[${Date.now()}] Reason:`, reason); console.error(`[${Date.now()}] Stack trace:`, reason?.stack || 'No stack trace available'); process.exit(1); }); if (require.main === module) { main().catch((error) => { console.error("Unhandled error on main():", error); process.exit(1); }); }

Here is a stack trace for the error that escapes:

Trace: BUSYGROUP Consumer Group name already exists at new ErrorReply (/app/node_modules/@redis/client/lib/errors.ts:70:4) at new SimpleError (/appi/node_modules/@redis/client/dist/lib/errors.js:76:1) at Decoder.#decodeSimpleError (/app/node_modules/@redis/client/lib/RESP/decoder.ts:650:7) at Decoder.#decodeTypeValue (/app/node_modules/@redis/client/lib/RESP/decoder.ts:171:34) at Decoder.write (/app/node_modules/@redis/client/lib/RESP/decoder.ts:90:32) at RedisSocket.<anonymous> (/app/node_modules/@redis/client/lib/client/index.ts:694:31) at RedisSocket.emit (node:events:519:28) at RedisSocket.emit (node:domain:488:12) at Socket.<anonymous> (/app/node_modules/@redis/client/lib/client/socket.ts:275:32) at Socket.emit (node:events:519:28)

Node.js Version

18

Redis Server Version

7.2

Node Redis Version

5.6.1

Platform

macOS/Docker

Logs

Attempting group op 0 TRY BLOCK - result OK Attempting group op 1 [1753419722500] CATCH BLOCK - error caught: [SimpleError: BUSYGROUP Consumer Group name already exists] [1753419722501] CATCH BLOCK - error type: object [1753419722501] CATCH BLOCK - error constructor: SimpleError [1753419722501] CATCH BLOCK - BUSYGROUP error handled Attempting group op 2 [1753419722501] UNHANDLED REJECTION at: Promise { <rejected> [SimpleError: BUSYGROUP Consumer Group name already exists] } [1753419722501] Reason: [SimpleError: BUSYGROUP Consumer Group name already exists] [1753419722501] Stack trace: No stack trace available

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions