From 519825a651fe22042a73046824d12f03f56ca9e2 Mon Sep 17 00:00:00 2001 From: DD Date: Sat, 25 Mar 2023 14:49:35 +0200 Subject: [PATCH] fix(WebSocketShard): don't await #destroy in error bubbling logic (#9276) * fix(WebSocketShard): don't await #destroy in error bubbling logic * fix: properly throw abort errors * chore: vlad's nit --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/ws/README.md | 4 +++- packages/ws/src/ws/WebSocketShard.ts | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/ws/README.md b/packages/ws/README.md index 6e4a36814..ca994d9e2 100644 --- a/packages/ws/README.md +++ b/packages/ws/README.md @@ -39,7 +39,7 @@ pnpm add @discordjs/ws ## Example usage ```ts -import { WebSocketManager, WebSocketShardEvents } from '@discordjs/ws'; +import { WebSocketManager, WebSocketShardEvents, CompressionMethod } from '@discordjs/ws'; import { REST } from '@discordjs/rest'; const rest = new REST().setToken(process.env.DISCORD_TOKEN); @@ -48,6 +48,8 @@ const manager = new WebSocketManager({ token: process.env.DISCORD_TOKEN, intents: 0, // for no intents rest, + // uncomment if you have zlib-sync installed and want to use compression + // compression: CompressionMethod.ZlibStream, }); manager.on(WebSocketShardEvents.Dispatch, (event) => { diff --git a/packages/ws/src/ws/WebSocketShard.ts b/packages/ws/src/ws/WebSocketShard.ts index 5cdd15a33..70347d0d8 100644 --- a/packages/ws/src/ws/WebSocketShard.ts +++ b/packages/ws/src/ws/WebSocketShard.ts @@ -279,16 +279,18 @@ export class WebSocketShard extends AsyncEventEmitter { await promise; return { ok: true }; } catch (error) { + const isAbortError = error instanceof Error && error.name === 'AbortError'; + // Any error that isn't an abort error would have been caused by us emitting an error event in the first place // See https://nodejs.org/api/events.html#eventsonceemitter-name-options for `once()` behavior - if (error instanceof Error && error.name === 'AbortError') { - this.emit(WebSocketShardEvents.Error, { error }); + if (isAbortError) { + this.emit(WebSocketShardEvents.Error, { error: error as Error }); } // As stated previously, any other error would have been caused by us emitting the error event, which looks // like { error: unknown } // eslint-disable-next-line no-ex-assign - error = (error as { error: unknown }).error; + error = error instanceof Error ? error : (error as { error: unknown }).error; // If the user has no handling on their end (error event) simply throw. // We also want to throw if we're still in the initial `connect()` call, since that's the only time @@ -298,7 +300,7 @@ export class WebSocketShard extends AsyncEventEmitter { } // If the error is handled, we can just try to reconnect - await this.destroy({ + void this.destroy({ code: CloseCodes.Normal, reason: 'Something timed out or went wrong while waiting for an event', recover: WebSocketShardDestroyRecovery.Reconnect,