Typehint error.py
This commit is contained in:
parent
0fae0b4995
commit
a8db8546db
@ -22,6 +22,21 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import Dict, List, Optional, TYPE_CHECKING, Any, Tuple, Union
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from aiohttp import ClientResponse, ClientWebSocketResponse
|
||||
|
||||
try:
|
||||
from requests import Response
|
||||
|
||||
ResponseType = Union[ClientResponse, Response]
|
||||
except ModuleNotFoundError:
|
||||
ResponseType = ClientResponse
|
||||
|
||||
from .interactions import Interaction
|
||||
|
||||
__all__ = (
|
||||
'DiscordException',
|
||||
'ClientException',
|
||||
@ -39,41 +54,49 @@ __all__ = (
|
||||
'InteractionResponded',
|
||||
)
|
||||
|
||||
|
||||
class DiscordException(Exception):
|
||||
"""Base exception class for discord.py
|
||||
|
||||
Ideally speaking, this could be caught to handle any exceptions raised from this library.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class ClientException(DiscordException):
|
||||
"""Exception that's raised when an operation in the :class:`Client` fails.
|
||||
|
||||
These are usually for exceptions that happened due to user input.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class NoMoreItems(DiscordException):
|
||||
"""Exception that is raised when an async iteration operation has no more
|
||||
items."""
|
||||
"""Exception that is raised when an async iteration operation has no more items."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class GatewayNotFound(DiscordException):
|
||||
"""An exception that is raised when the gateway for Discord could not be found"""
|
||||
|
||||
def __init__(self):
|
||||
message = 'The gateway to connect to discord was not found.'
|
||||
super().__init__(message)
|
||||
|
||||
def flatten_error_dict(d, key=''):
|
||||
items = []
|
||||
|
||||
def _flatten_error_dict(d: Dict[str, Any], key: str = '') -> Dict[str, str]:
|
||||
items: List[Tuple[str, str]] = []
|
||||
for k, v in d.items():
|
||||
new_key = key + '.' + k if key else k
|
||||
|
||||
if isinstance(v, dict):
|
||||
try:
|
||||
_errors = v['_errors']
|
||||
_errors: List[Dict[str, Any]] = v['_errors']
|
||||
except KeyError:
|
||||
items.extend(flatten_error_dict(v, new_key).items())
|
||||
items.extend(_flatten_error_dict(v, new_key).items())
|
||||
else:
|
||||
items.append((new_key, ' '.join(x.get('message', '') for x in _errors)))
|
||||
else:
|
||||
@ -81,6 +104,7 @@ def flatten_error_dict(d, key=''):
|
||||
|
||||
return dict(items)
|
||||
|
||||
|
||||
class HTTPException(DiscordException):
|
||||
"""Exception that's raised when an HTTP request operation fails.
|
||||
|
||||
@ -99,21 +123,23 @@ class HTTPException(DiscordException):
|
||||
The Discord specific error code for the failure.
|
||||
"""
|
||||
|
||||
def __init__(self, response, message):
|
||||
self.response = response
|
||||
self.status = response.status
|
||||
def __init__(self, response: ResponseType, message: Optional[Union[str, Dict[str, Any]]]):
|
||||
self.response: ResponseType = response
|
||||
self.status: int = response.status # type: ignore
|
||||
self.code: int
|
||||
self.text: str
|
||||
if isinstance(message, dict):
|
||||
self.code = message.get('code', 0)
|
||||
base = message.get('message', '')
|
||||
errors = message.get('errors')
|
||||
if errors:
|
||||
errors = flatten_error_dict(errors)
|
||||
errors = _flatten_error_dict(errors)
|
||||
helpful = '\n'.join('In %s: %s' % t for t in errors.items())
|
||||
self.text = base + '\n' + helpful
|
||||
else:
|
||||
self.text = base
|
||||
else:
|
||||
self.text = message
|
||||
self.text = message or ''
|
||||
self.code = 0
|
||||
|
||||
fmt = '{0.status} {0.reason} (error code: {1})'
|
||||
@ -122,20 +148,25 @@ class HTTPException(DiscordException):
|
||||
|
||||
super().__init__(fmt.format(self.response, self.code, self.text))
|
||||
|
||||
|
||||
class Forbidden(HTTPException):
|
||||
"""Exception that's raised for when status code 403 occurs.
|
||||
|
||||
Subclass of :exc:`HTTPException`
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class NotFound(HTTPException):
|
||||
"""Exception that's raised for when status code 404 occurs.
|
||||
|
||||
Subclass of :exc:`HTTPException`
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class DiscordServerError(HTTPException):
|
||||
"""Exception that's raised for when a 500 range status code occurs.
|
||||
|
||||
@ -143,14 +174,18 @@ class DiscordServerError(HTTPException):
|
||||
|
||||
.. versionadded:: 1.5
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class InvalidData(ClientException):
|
||||
"""Exception that's raised when the library encounters unknown
|
||||
or invalid data from Discord.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class InvalidArgument(ClientException):
|
||||
"""Exception that's raised when an argument to a function
|
||||
is invalid some way (e.g. wrong value or wrong type).
|
||||
@ -159,15 +194,19 @@ class InvalidArgument(ClientException):
|
||||
``TypeError`` except inherited from :exc:`ClientException` and thus
|
||||
:exc:`DiscordException`.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class LoginFailure(ClientException):
|
||||
"""Exception that's raised when the :meth:`Client.login` function
|
||||
fails to log you in from improper credentials or some other misc.
|
||||
failure.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class ConnectionClosed(ClientException):
|
||||
"""Exception that's raised when the gateway connection is
|
||||
closed for reasons that could not be handled internally.
|
||||
@ -181,15 +220,17 @@ class ConnectionClosed(ClientException):
|
||||
shard_id: Optional[:class:`int`]
|
||||
The shard ID that got closed if applicable.
|
||||
"""
|
||||
def __init__(self, socket, *, shard_id, code=None):
|
||||
|
||||
def __init__(self, socket: ClientWebSocketResponse, *, shard_id: Optional[int], code: Optional[int] = None):
|
||||
# This exception is just the same exception except
|
||||
# reconfigured to subclass ClientException for users
|
||||
self.code = code or socket.close_code
|
||||
self.code: int = code or socket.close_code or -1
|
||||
# aiohttp doesn't seem to consistently provide close reason
|
||||
self.reason = ''
|
||||
self.shard_id = shard_id
|
||||
self.reason: str = ''
|
||||
self.shard_id: Optional[int] = shard_id
|
||||
super().__init__(f'Shard ID {self.shard_id} WebSocket closed with {self.code}')
|
||||
|
||||
|
||||
class PrivilegedIntentsRequired(ClientException):
|
||||
"""Exception that's raised when the gateway is requesting privileged intents
|
||||
but they're not ticked in the developer page yet.
|
||||
@ -206,14 +247,17 @@ class PrivilegedIntentsRequired(ClientException):
|
||||
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.'
|
||||
def __init__(self, shard_id: Optional[int]):
|
||||
self.shard_id: Optional[int] = 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)
|
||||
|
||||
|
||||
class InteractionResponded(ClientException):
|
||||
"""Exception that's raised when sending another interaction response using
|
||||
:class:`InteractionResponse` when one has already been done before.
|
||||
@ -228,6 +272,6 @@ class InteractionResponded(ClientException):
|
||||
The interaction that's already been responded to.
|
||||
"""
|
||||
|
||||
def __init__(self, interaction):
|
||||
self.interaction = interaction
|
||||
def __init__(self, interaction: Interaction):
|
||||
self.interaction: Interaction = interaction
|
||||
super().__init__('This interaction has already been responded to before')
|
||||
|
Loading…
x
Reference in New Issue
Block a user