diff --git a/packages/ws/__tests__/ws/WebSocketManager.test.ts b/packages/ws/__tests__/ws/WebSocketManager.test.ts index bf652971d..ba3a75a08 100644 --- a/packages/ws/__tests__/ws/WebSocketManager.test.ts +++ b/packages/ws/__tests__/ws/WebSocketManager.test.ts @@ -183,6 +183,34 @@ test('strategies', async () => { const strategy = new MockStrategy(); manager.setStrategy(strategy); + const data: APIGatewayBotInfo = { + shards: 1, + session_start_limit: { + max_concurrency: 3, + reset_after: 60, + remaining: 3, + total: 3, + }, + url: 'wss://gateway.discord.gg', + }; + + const fetch = vi.fn(() => ({ + data, + statusCode: 200, + responseOptions: { + headers: { + 'content-type': 'application/json', + }, + }, + })); + + mockPool + .intercept({ + path: '/api/v10/gateway/bot', + method: 'GET', + }) + .reply(fetch); + await manager.connect(); expect(strategy.spawn).toHaveBeenCalledWith(shardIds); expect(strategy.connect).toHaveBeenCalled(); diff --git a/packages/ws/src/ws/WebSocketManager.ts b/packages/ws/src/ws/WebSocketManager.ts index 810384f5b..42458ec78 100644 --- a/packages/ws/src/ws/WebSocketManager.ts +++ b/packages/ws/src/ws/WebSocketManager.ts @@ -271,6 +271,16 @@ export class WebSocketManager extends AsyncEventEmitter { public async connect() { const shardCount = await this.getShardCount(); + + const data = await this.fetchGatewayInformation(); + if (data.session_start_limit.remaining < shardCount) { + throw new Error( + `Not enough sessions remaining to spawn ${shardCount} shards; only ${ + data.session_start_limit.remaining + } remaining; resets at ${new Date(Date.now() + data.session_start_limit.reset_after).toISOString()}`, + ); + } + // First, make sure all our shards are spawned await this.updateShardCount(shardCount); await this.strategy.connect();