Skip to content

Commit

Permalink
feat(gateway): add reasons to close event codes (#881)
Browse files Browse the repository at this point in the history

Signed-off-by: Snipy7374 <davidecucci07@gmail.com>
Co-authored-by: shiftinv <8530778+shiftinv@users.noreply.github.com>
  • Loading branch information
Snipy7374 and shiftinv committed Jan 14, 2023
1 parent a2d7e7c commit 84c44a2
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
1 change: 1 addition & 0 deletions changelog/873.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Adds reasons/descriptions to :exc:`ConnectionClosed` errors.
40 changes: 38 additions & 2 deletions disnake/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,20 +224,56 @@ class ConnectionClosed(ClientException):
The shard ID that got closed if applicable.
"""

# https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-close-event-codes
GATEWAY_CLOSE_EVENT_REASONS: Dict[int, str] = {
4000: "Unknown error",
4001: "Unknown opcode",
4002: "Decode error",
4003: "Not authenticated",
4004: "Authentication failed",
4005: "Already authenticated",
4007: "Invalid sequence",
4008: "Rate limited",
4009: "Session timed out",
4010: "Invalid Shard",
4011: "Sharding required - you are required to shard your connection in order to connect.",
4012: "Invalid API version",
4013: "Invalid intents",
4014: "Disallowed intents - you tried to specify an intent that you have not enabled or are not approved for.",
}

# https://discord.com/developers/docs/topics/opcodes-and-status-codes#voice-voice-close-event-codes
GATEWAY_VOICE_CLOSE_EVENT_REASONS: Dict[int, str] = {
**GATEWAY_CLOSE_EVENT_REASONS,
4002: "Failed to decode payload",
4006: "Session no longer valid",
4011: "Server not found",
4012: "Unknown protocol",
4014: "Disconnected, channel was deleted, you were kicked, voice server changed, or the main gateway session was dropped.",
4015: "Voice server crashed",
4016: "Unknown encryption mode",
}

def __init__(
self,
socket: ClientWebSocketResponse,
*,
shard_id: Optional[int],
code: Optional[int] = None,
voice: bool = False,
) -> None:
# This exception is just the same exception except
# reconfigured to subclass ClientException for users
self.code: int = code or socket.close_code or -1
# aiohttp doesn't seem to consistently provide close reason
self.reason: str = ""
self.reason: str = self.GATEWAY_CLOSE_EVENT_REASONS.get(self.code, "Unknown reason")
if voice:
self.reason = self.GATEWAY_VOICE_CLOSE_EVENT_REASONS.get(self.code, "Unknown reason")

self.shard_id: Optional[int] = shard_id
super().__init__(f"Shard ID {self.shard_id} WebSocket closed with {self.code}")
super().__init__(
f"Shard ID {self.shard_id} WebSocket closed with {self.code}: {self.reason}"
)


class PrivilegedIntentsRequired(ClientException):
Expand Down
4 changes: 2 additions & 2 deletions disnake/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -1076,14 +1076,14 @@ async def poll_event(self) -> None:
await self.received_message(utils._from_json(msg.data))
elif msg.type is aiohttp.WSMsgType.ERROR:
_log.debug("Received %s", msg)
raise ConnectionClosed(self.ws, shard_id=None) from msg.data
raise ConnectionClosed(self.ws, shard_id=None, voice=True) from msg.data
elif msg.type in (
aiohttp.WSMsgType.CLOSED,
aiohttp.WSMsgType.CLOSE,
aiohttp.WSMsgType.CLOSING,
):
_log.debug("Received %s", msg)
raise ConnectionClosed(self.ws, shard_id=None, code=self._close_code)
raise ConnectionClosed(self.ws, shard_id=None, code=self._close_code, voice=True)

async def close(self, code: int = 1000) -> None:
if self._keep_alive is not None:
Expand Down

0 comments on commit 84c44a2

Please sign in to comment.