From bf8ca5899689863487a4ec1c343ead9a874cbde9 Mon Sep 17 00:00:00 2001 From: Rapptz Date: Mon, 14 Sep 2020 03:49:21 -0400 Subject: [PATCH] Add a special exception for required privileged intents --- discord/client.py | 2 ++ discord/errors.py | 24 ++++++++++++++++++++++++ discord/shard.py | 20 +++++++++++++++++--- docs/api.rst | 3 +++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/discord/client.py b/discord/client.py index 861617b74..6be3e9822 100644 --- a/discord/client.py +++ b/discord/client.py @@ -573,6 +573,8 @@ class Client: # sometimes, discord sends us 1000 for unknown reasons so we should reconnect # regardless and rely on is_closed instead if isinstance(exc, ConnectionClosed): + if exc.code == 4014: + raise PrivilegedIntentsRequired(exc.shard_id) from None if exc.code != 1000: await self.close() raise diff --git a/discord/errors.py b/discord/errors.py index bd78131a4..be3015cca 100644 --- a/discord/errors.py +++ b/discord/errors.py @@ -175,3 +175,27 @@ class ConnectionClosed(ClientException): self.reason = '' self.shard_id = shard_id super().__init__('Shard ID %s WebSocket closed with %s' % (self.shard_id, self.code)) + +class PrivilegedIntentsRequired(ClientException): + """Exception that's thrown when the gateway is requesting privileged intents + but they're not ticked in the developer page yet. + + Go to https://discord.com/developers/applications/ and enable the intents + that are required. Currently these are as follows: + + - :attr:`Intents.members` + - :attr:`Intents.presences` + + Attributes + ----------- + shard_id: Optional[:class:`int`] + The shard ID that got closed if applicable. + """ + + def __init__(self, shard_id): + self.shard_id = shard_id + msg = 'Shard ID %s is requesting privileged intents that have not been explicitly enabled in the ' \ + 'developer portal. It is recommended to go to https://discord.com/developers/applications/ ' \ + 'and explicitly enable the privileged intents within your application\'s page. If this is not ' \ + 'possible, then consider disabling the privileged intents instead.' + super().__init__(msg % shard_id) diff --git a/discord/shard.py b/discord/shard.py index 00a7a1178..3587c097b 100644 --- a/discord/shard.py +++ b/discord/shard.py @@ -34,7 +34,15 @@ from .state import AutoShardedConnectionState from .client import Client from .backoff import ExponentialBackoff from .gateway import * -from .errors import ClientException, InvalidArgument, HTTPException, GatewayNotFound, ConnectionClosed +from .errors import ( + ClientException, + InvalidArgument, + HTTPException, + GatewayNotFound, + ConnectionClosed, + PrivilegedIntentsRequired, +) + from . import utils from .enums import Status @@ -125,6 +133,9 @@ class Shard: return if isinstance(e, ConnectionClosed): + if e.code == 4014: + self._queue_put(EventItem(EventType.terminate, self, PrivilegedIntentsRequired(self.id))) + return if e.code != 1000: self._queue_put(EventItem(EventType.close, self, e)) return @@ -408,8 +419,11 @@ class AutoShardedClient(Client): item = await self.__queue.get() if item.type == EventType.close: await self.close() - if isinstance(item.error, ConnectionClosed) and item.error.code != 1000: - raise item.error + if isinstance(item.error, ConnectionClosed): + if item.error.code != 1000: + raise item.error + if item.error.code == 4014: + raise PrivilegedIntentsRequired(item.shard.id) from None return elif item.type in (EventType.identify, EventType.resume): await item.shard.reidentify(item.error) diff --git a/docs/api.rst b/docs/api.rst index b3c10991f..d697b4f3c 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -2937,6 +2937,8 @@ The following exceptions are thrown by the library. .. autoexception:: ConnectionClosed +.. autoexception:: PrivilegedIntentsRequired + .. autoexception:: discord.opus.OpusError .. autoexception:: discord.opus.OpusNotLoaded @@ -2953,6 +2955,7 @@ Exception Hierarchy - :exc:`InvalidArgument` - :exc:`LoginFailure` - :exc:`ConnectionClosed` + - :exc:`PrivilegedIntentsRequired` - :exc:`NoMoreItems` - :exc:`GatewayNotFound` - :exc:`HTTPException`