Browse Source

Improve captcha handling errors, remove unnecessary HTTP request

pull/10109/head
dolfies 3 years ago
parent
commit
2e5bd8f31a
  1. 3
      discord/client.py
  2. 14
      discord/errors.py
  3. 29
      discord/http.py

3
discord/client.py

@ -1376,7 +1376,8 @@ class Client:
payload['status'] = status payload['status'] = status
if custom_activity != getattr(self.user.settings, 'custom_activity', None): # type: ignore # user is always present when logged in if custom_activity != getattr(self.user.settings, 'custom_activity', None): # type: ignore # user is always present when logged in
payload['custom_activity'] = custom_activity payload['custom_activity'] = custom_activity
await self.user.edit_settings(**payload) # type: ignore # user is always present when logged in if payload:
await self.user.edit_settings(**payload) # type: ignore # user is always present when logged in
status_str = str(status) status_str = str(status)
activities_tuple = tuple(a.to_dict() for a in activities) activities_tuple = tuple(a.to_dict() for a in activities)

14
discord/errors.py

@ -47,6 +47,7 @@ __all__ = (
'AuthFailure', 'AuthFailure',
'LoginFailure', 'LoginFailure',
'ConnectionClosed', 'ConnectionClosed',
'CaptchaRequired',
) )
@ -169,6 +170,19 @@ class DiscordServerError(HTTPException):
pass pass
class CaptchaRequired(HTTPException):
"""Exception that's raised when a captcha is required and no handler exists.
Subclass of :exc:`HTTPException`.
.. versionadded:: 2.0
"""
def __init__(self, response: _ResponseType, message: Dict[str, Any]):
super().__init__(response, {'code': -1, 'message': 'Captcha required'})
self.json = message
class InvalidData(ClientException): class InvalidData(ClientException):
"""Exception that's raised when the library encounters unknown """Exception that's raised when the library encounters unknown
or invalid data from Discord. or invalid data from Discord.

29
discord/http.py

@ -52,7 +52,7 @@ import weakref
import aiohttp import aiohttp
from .enums import RelationshipAction, InviteType from .enums import RelationshipAction, InviteType
from .errors import HTTPException, Forbidden, NotFound, LoginFailure, DiscordServerError from .errors import HTTPException, Forbidden, NotFound, LoginFailure, DiscordServerError, CaptchaRequired
from .file import File from .file import File
from .tracking import ContextProperties from .tracking import ContextProperties
from . import utils from . import utils
@ -470,7 +470,7 @@ class HTTPClient:
if reason: if reason:
headers['X-Audit-Log-Reason'] = _uriquote(reason) headers['X-Audit-Log-Reason'] = _uriquote(reason)
if payload := kwargs.pop('json', None): if payload := kwargs.pop('json', None) is not None:
headers['Content-Type'] = 'application/json' headers['Content-Type'] = 'application/json'
kwargs['data'] = utils._to_json(payload) kwargs['data'] = utils._to_json(payload)
@ -569,6 +569,8 @@ class HTTPClient:
elif response.status >= 500: elif response.status >= 500:
raise DiscordServerError(response, data) raise DiscordServerError(response, data)
else: else:
if 'captcha_key' in data:
raise CaptchaRequired(response, data) # type: ignore # Should not be text at this point
raise HTTPException(response, data) raise HTTPException(response, data)
# This is handling exceptions from the request # This is handling exceptions from the request
@ -580,22 +582,17 @@ class HTTPClient:
raise raise
# Captcha handling # Captcha handling
except HTTPException as e: except CaptchaRequired as e:
try: values = [i for i in e.json['captcha_key'] if any(value in i for value in CAPTCHA_VALUES)]
captcha_key = data['captcha_key'] # type: ignore # Handled below if captcha_handler is None or tries == 4:
except (KeyError, TypeError): raise
elif not values:
raise raise
else: else:
values = [i for i in captcha_key if any(value in i for value in CAPTCHA_VALUES)] previous = payload or {}
if captcha_handler is None or tries == 4: previous['captcha_key'] = await captcha_handler.fetch_token(e.json, self.proxy, self.proxy_auth)
raise HTTPException(e.response, {'code': -1, 'message': 'Captcha required'}) from e kwargs['headers']['Content-Type'] = 'application/json'
elif not values: kwargs['data'] = utils._to_json(previous)
raise
else:
previous = payload or {}
previous['captcha_key'] = await captcha_handler.fetch_token(data, self.proxy, self.proxy_auth) # type: ignore # data is json here
kwargs['headers']['Content-Type'] = 'application/json'
kwargs['data'] = utils._to_json(previous)
if response is not None: if response is not None:
# We've run out of retries, raise # We've run out of retries, raise

Loading…
Cancel
Save