diff --git a/.changeset/await-socket-mode-shutdown.md b/.changeset/await-socket-mode-shutdown.md new file mode 100644 index 000000000..ef59aad28 --- /dev/null +++ b/.changeset/await-socket-mode-shutdown.md @@ -0,0 +1,5 @@ +--- +'@slack/bolt': patch +--- + +Await Socket Mode client shutdown before resolving `SocketModeReceiver.stop()`. diff --git a/src/receivers/SocketModeReceiver.ts b/src/receivers/SocketModeReceiver.ts index 98efe1e97..52b66dd9a 100644 --- a/src/receivers/SocketModeReceiver.ts +++ b/src/receivers/SocketModeReceiver.ts @@ -260,20 +260,13 @@ export default class SocketModeReceiver implements Receiver { return this.client.start(); } - public stop(): Promise { + public async stop(): Promise { if (this.httpServer !== undefined) { // This HTTP server is only for the OAuth flow support this.httpServer.close((error) => { if (error) this.logger.error(`Failed to shutdown the HTTP server for OAuth flow: ${error}`); }); } - return new Promise((resolve, reject) => { - try { - this.client.disconnect(); - resolve(); - } catch (error) { - reject(error); - } - }); + await this.client.disconnect(); } } diff --git a/test/unit/receivers/SocketModeReceiver.spec.ts b/test/unit/receivers/SocketModeReceiver.spec.ts index ffdca6997..c8ec3a112 100644 --- a/test/unit/receivers/SocketModeReceiver.spec.ts +++ b/test/unit/receivers/SocketModeReceiver.spec.ts @@ -649,5 +649,32 @@ describe('SocketModeReceiver', () => { await receiver.stop(); assert(clientStub.disconnect.called); }); + + it('should wait for SocketModeClient to disconnect', async () => { + const clientStub = sinon.createStubInstance(SocketModeClient); + let resolveDisconnect = () => { + throw new Error('SocketModeClient.disconnect() was not invoked'); + }; + clientStub.disconnect.callsFake( + () => + new Promise((resolve) => { + resolveDisconnect = resolve; + }), + ); + const SocketModeReceiver = await importSocketModeReceiver(overrides); + const receiver = new SocketModeReceiver({ appToken: 'my-secret', logger: noopLogger }); + receiver.client = clientStub as unknown as SocketModeClient; + + let stopped = false; + const stopPromise = receiver.stop().then(() => { + stopped = true; + }); + await Promise.resolve(); + + assert.isFalse(stopped); + resolveDisconnect(); + await stopPromise; + assert.isTrue(stopped); + }); }); });