From 6546f63ad752ec147dd32bed7f092d9d7e53f6f6 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 b9d0f446..36df67b6 100644 --- a/discord/client.py +++ b/discord/client.py @@ -570,6 +570,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 bd78131a..be3015cc 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 2ed7724d..8e5b75cd 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 @@ -407,8 +418,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 7a31e9c2..0a2f5521 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -2924,6 +2924,8 @@ The following exceptions are thrown by the library. .. autoexception:: ConnectionClosed +.. autoexception:: PrivilegedIntentsRequired + .. autoexception:: discord.opus.OpusError .. autoexception:: discord.opus.OpusNotLoaded @@ -2940,6 +2942,7 @@ Exception Hierarchy - :exc:`InvalidArgument` - :exc:`LoginFailure` - :exc:`ConnectionClosed` + - :exc:`PrivilegedIntentsRequired` - :exc:`NoMoreItems` - :exc:`GatewayNotFound` - :exc:`HTTPException`