When calling app.close()
on a redis microservice server, an uncaught error will be thrown.
~/node_modules/.pnpm/ioredis@5.2.2/node_modules/ioredis/built/redis/event_handler.js:182
self.flushQueue(new Error(utils_1.CONNECTION_CLOSED_ERROR_MSG));
^
Error: Connection is closed.
at close (~/node_modules/.pnpm/ioredis@5.2.2/node_modules/ioredis/built/redis/event_handler.js:182:25)
at Socket.<anonymous> (~/node_modules/.pnpm/ioredis@5.2.2/node_modules/ioredis/built/redis/event_handler.js:149:20)
at Object.onceWrapper (node:events:628:26)
at Socket.emit (node:events:513:28)
at TCP.<anonymous> (node:net:757:14)
The server closes without any kind of errors on SIGINT or app.close()
. I found this during integration testing of my ogma library where I programatically open and close servers to verify an interceptor works as expected.
- clone this repo
npm i
/yarn
/pnpm i
docker compsoe up -d
npm run start:dev
/yarn start:dev
/pnpm start:dev
- observe the error
The error arises because the server is being clsoed multiple times when app.close()
is called. It looks like app.close()
ends up calling app.dispose()
which calls to the MicroserviceModule.services.close()
(pseudocode) which doubles the call to the clsoe method. As ioredis has already closed the conenction, this throws an error.
A solution I played around with locally is to create a protected isClosed
variable on the server.ts
file in @nestjs/microservices
and have all of the server-*.ts
files check for this.isClosed
before going through the close steps and returning early if it is already closed.