diff --git a/interactions/api/error.py b/interactions/api/error.py index 745df97fb..e5acc9014 100644 --- a/interactions/api/error.py +++ b/interactions/api/error.py @@ -1,77 +1,77 @@ -from enum import IntEnum -from string import Formatter -from typing import Any, Optional, Union +from logging import getLogger +from typing import List, Optional -__all__ = ( - "ErrorFormatter", - "InteractionException", - "GatewayException", - "HTTPException", - "JSONException", -) +__all__ = ("LibraryException",) +log = getLogger(__name__) -class ErrorFormatter(Formatter): - """A customized error formatting script to return specific errors.""" - def get_value(self, key, args, kwargs) -> Any: - if not isinstance(key, str): - return Formatter.get_value(self, key=key, args=args, kwargs=kwargs) - try: - return kwargs[key] - except KeyError: - return key +class LibraryException(Exception): + code: Optional[int] + severity: int + __slots__ = {"code", "severity", "message", "data"} -class InteractionException(Exception): - """ - An exception class for interactions. - - .. note:: - This is a WIP. This isn't meant to be used yet, this is a baseline, - and for extensive testing/review before integration. - Likewise, this will show the concepts before use, and will be refined when time goes on. - - :ivar interactions.api.error.ErrorFormatter _formatter: The built-in formatter. - :ivar dict _lookup: A dictionary containing the values from the built-in Enum. - - """ - - __slots__ = ("_type", "_lookup", "__type", "_formatter", "kwargs") - - def __init__(self, __type: Optional[Union[int, IntEnum]] = 0, **kwargs) -> None: + @staticmethod + def _parse(_data: dict) -> List[tuple]: """ - :param __type: Type of error. This is decided from an IntEnum, which gives readable error messages instead of - typical error codes. Subclasses of this class works fine, and so does regular integers. - :type __type: Optional[Union[int, IntEnum]] - :param kwargs: Any additional keyword arguments. - :type **kwargs: dict - - :: note:: - (given if 3 is "DUPLICATE_COMMAND" and with the right enum import, it will display 3 as the error code.) - Example: + Internal function that should not be executed externally. + Parse the error data and set the code and message. - >>> raise InteractionException(2, message="msg") - Exception raised: "msg" (error 2) - - >>> raise InteractionException(Default_Error_Enum.DUPLICATE_COMMAND) # noqa - Exception raised: Duplicate command name. (error 3) + :param _data: The error data to parse. + :type _data: dict + :return: A list of tuples containing parsed errors. + :rtype: List[tuple] """ + _errors: list = [] + + def _inner(v, parent): + if isinstance(v, dict): + if (errs := v.get("_errors")) and isinstance(errs, list): + for err in errs: + _errors.append((err["code"], err["message"], parent)) + else: + for k, v in v.items(): + if isinstance(v, dict): + _inner(v, parent + "." + k) + elif isinstance(v, list): + for e in v: + if isinstance(e, dict): + _errors.append((e["code"], e["message"], parent + "." + k)) + elif isinstance(v, list) and parent == "_errors": + for e in v: + _errors.append((e["code"], e["message"], parent)) + + for _k, _v in _data.items(): + _inner(_v, _k) + return _errors + + def log(self, message: str, *args): + """ + Log the error message. - self._type = __type - self.kwargs = kwargs - self._formatter = ErrorFormatter() - self._lookup = self.lookup() - - self.error() + :param message: + :type message: + :param args: + :type args: + """ + if self.severity == 0: # NOTSET + pass + elif self.severity == 10: # DEBUG + log.debug(message, *args) + elif self.severity == 20: # INFO + log.info(message, *args) + elif self.severity == 30: # WARNING + log.warning(message, *args) + elif self.severity == 40: # ERROR + log.error(message, *args) + elif self.severity == 50: # CRITICAL + log.critical(message, *args) @staticmethod - def lookup() -> dict: - """ - From the default error enum integer declaration, - generate a dictionary containing the phrases used for the errors. - """ + def lookup(code: int) -> str: return { + # Default error integer enum 0: "Unknown error", 1: "Request to Discord API has failed.", 2: "Some formats are incorrect. See Discord API DOCS for proper format.", @@ -84,87 +84,15 @@ def lookup() -> dict: 9: "Incorrect data was passed to a slash command data object.", 10: "The interaction was already responded to.", 11: "Error creating your command.", - } - - @property - def type(self) -> Optional[Union[int, IntEnum]]: - """ - Grabs the type attribute. - Primarily useful to use it in conditions for integral v4 (potential) logic. - """ - return self._type - - def error(self) -> None: - """This calls the exception.""" - _err_val = "" - _err_unidentifiable = False - _empty_space = " " - _overrided = "message" in self.kwargs - - if issubclass(type(self._type), IntEnum): - _err_val = self.type.name - _err_rep = self.type.value - elif type(self.type) == int: - _err_rep = self.type - else: # unidentifiable. - _err_rep = 0 - _err_unidentifiable = True - - _err_msg = _default_err_msg = "Error code: {_err_rep}" - - if self.kwargs != {} and _overrided: - _err_msg = self.kwargs["message"] - - self.kwargs["_err_rep"] = _err_rep - - if not _err_unidentifiable: - lookup_str = self._lookup[_err_rep] if _err_rep in self._lookup.keys() else _err_val - _lookup_str = ( - lookup_str - if max(self._lookup.keys()) >= _err_rep >= min(self._lookup.keys()) - else "" - ) - else: - _lookup_str = lookup_str = "" - - custom_err_str = ( - self._formatter.format(_err_msg, **self.kwargs) - if "_err_rep" in _err_msg - else self._formatter.format(_err_msg + _empty_space + _default_err_msg, **self.kwargs) - ) - - # This is just for writing notes meant to be for the developer(testers): - # - # Error code 4 represents dupe callback. In v3, that's "Duplicate component callback detected: " - # f"message ID {message_id or ''}, " - # f"custom_id `{custom_id or ''}`, " - # f"component_type `{component_type or ''}`" - # - # Error code 3 represents dupe command, i.e. "Duplicate command name detected: {name}" - # Error code 1 represents Req. failure, i.e. "Request failed with resp: {self.status} | {self.msg}" - # - - super().__init__( - f"{f'{lookup_str} ' if _err_val != '' else f'{_lookup_str + _empty_space if max(self._lookup.keys()) >= _err_rep >= min(self._lookup.keys()) else lookup_str}'}{custom_err_str}" - ) - - -class GatewayException(InteractionException): - """ - This is a derivation of InteractionException in that this is used to represent Gateway closing OP codes. - - :ivar ErrorFormatter _formatter: The built-in formatter. - :ivar dict _lookup: A dictionary containing the values from the built-in Enum. - """ - - __slots__ = ("_type", "_lookup", "__type", "_formatter", "kwargs") - - def __init__(self, __type, **kwargs): - super().__init__(__type, **kwargs) - - @staticmethod - def lookup() -> dict: - return { + # HTTP errors + 400: "Bad Request. The request was improperly formatted, or the server couldn't understand it.", + 401: "Not authorized. Double check your token to see if it's valid.", + 403: "You do not have enough permissions to execute this.", + 404: "Resource does not exist.", + 405: "HTTP method not valid.", # ? + 429: "You are being rate limited. Please slow down on your requests.", # Definitely can be overclassed. + 502: "Gateway unavailable. Try again later.", + # Gateway errors 4000: "Unknown error. Try reconnecting?", 4001: "Unknown opcode. Check your gateway opcode and/or payload.", 4002: "Invalid payload.", @@ -179,52 +107,7 @@ def lookup() -> dict: 4012: "Invalid API version for the Gateway.", 4013: "Invalid intent(s).", 4014: "Some intent(s) requested are not allowed. Please double check.", - } - - -class HTTPException(InteractionException): - """ - This is a derivation of InteractionException in that this is used to represent HTTP Exceptions. - - :ivar ErrorFormatter _formatter: The built-in formatter. - :ivar dict _lookup: A dictionary containing the values from the built-in Enum. - """ - - __slots__ = ("_type", "_lookup", "__type", "_formatter", "kwargs") - - def __init__(self, __type, **kwargs): - super().__init__(__type, **kwargs) - - @staticmethod - def lookup() -> dict: - return { - 400: "Bad Request. The request was improperly formatted, or the server couldn't understand it.", - 401: "Not authorized. Double check your token to see if it's valid.", - 403: "You do not have enough permissions to execute this.", - 404: "Resource does not exist.", - 405: "HTTP method not valid.", # ? - 429: "You are being rate limited. Please slow down on your requests.", # Definitely can be overclassed. - 502: "Gateway unavailable. Try again later.", - } - - -class JSONException(InteractionException): - """ - This is a derivation of InteractionException in that this is used to represent JSON API Exceptions. - - :ivar ErrorFormatter _formatter: The built-in formatter. - :ivar dict _lookup: A dictionary containing the values from the built-in Enum. - """ - - __slots__ = ("_type", "_lookup", "__type", "_formatter", "kwargs") - - def __init__(self, __type, **kwargs): - super().__init__(__type, **kwargs) - - @staticmethod - def lookup() -> dict: - return { - 0: "Unknown Error.", + # JSON errors 10001: "Unknown Account.", 10002: "Unknown Application.", 10003: "Unknown Channel.", @@ -377,4 +260,25 @@ def lookup() -> dict: 170007: "Sticker animation duration exceeds maximum of 5 seconds", 180000: "Cannot update a finished event", 180002: "Failed to create stage needed for stage event", - } + }.get(code, f"Unknown error: {code}") + + def __init__(self, message: str = None, code: int = 0, severity: int = 0, **kwargs): + self.code: int = code + self.severity: int = severity + self.data: dict = kwargs.pop("data", None) + self.message: str = message or self.lookup(self.code) + _fmt_error: List[tuple] = [] + + if ( + self.data + and isinstance(self.data, dict) + and isinstance(self.data.get("errors", None), dict) + ): + _fmt_error: List[tuple] = self._parse(self.data["errors"]) + + super().__init__( + f"{self.message} (code: {self.code}, severity {self.severity})\n" + + "\n".join([f"Error at {e[2]}: {e[0]} - {e[1]}" for e in _fmt_error]) + if _fmt_error + else None + ) diff --git a/interactions/api/error.pyi b/interactions/api/error.pyi index af4862dcc..2ebf478b4 100644 --- a/interactions/api/error.pyi +++ b/interactions/api/error.pyi @@ -1,49 +1,14 @@ -from enum import IntEnum -from string import Formatter -from typing import Any, Dict, Optional, Union +from typing import Optional, List -class ErrorFormatter(Formatter): - def get_value(self, key, args, kwargs) -> Any: ... +class LibraryException(Exception): + message: Optional[str] + code: Optional[int] + severity: Optional[int] -class InteractionException(Exception): - _type: Union[int, IntEnum] - __type: Optional[Union[int, IntEnum]] - _formatter: ErrorFormatter - kwargs: Dict[str, Any] - _lookup: dict - def __init__(self, __type: Optional[Union[int, IntEnum]] = 0, **kwargs) -> None: ... @staticmethod - def lookup() -> dict: ... - @property - def type(self) -> Optional[Union[int, IntEnum]]: ... - def error(self) -> None: ... + def _parse(_data: dict) -> List[tuple]: ... -class GatewayException(InteractionException): - _type: Union[int, IntEnum] - __type: Optional[Union[int, IntEnum]] - _formatter: ErrorFormatter - kwargs: Dict[str, Any] - _lookup: dict - def __init__(self, __type, **kwargs): ... - @staticmethod - def lookup() -> dict: ... - -class HTTPException(InteractionException): - _type: Union[int, IntEnum] - __type: Optional[Union[int, IntEnum]] - _formatter: ErrorFormatter - kwargs: Dict[str, Any] - _lookup: dict - def __init__(self, __type, **kwargs): ... - @staticmethod - def lookup() -> dict: ... + def log(self, message: str, *args) -> None: ... -class JSONException(InteractionException): - _type: Union[int, IntEnum] - __type: Optional[Union[int, IntEnum]] - _formatter: ErrorFormatter - kwargs: Dict[str, Any] - _lookup: dict - def __init__(self, __type, **kwargs): ... @staticmethod - def lookup() -> dict: ... + def lookup(code: int) -> str: ... diff --git a/interactions/api/gateway/client.py b/interactions/api/gateway/client.py index 075ece295..529966c02 100644 --- a/interactions/api/gateway/client.py +++ b/interactions/api/gateway/client.py @@ -24,7 +24,7 @@ from ...client.models import Option from ..dispatch import Listener from ..enums import OpCodeType -from ..error import GatewayException +from ..error import LibraryException from ..http.client import HTTPClient from ..models.attrs_utils import MISSING from ..models.flags import Intents @@ -186,7 +186,7 @@ async def _establish_connection( break if self._client.close_code in range(4010, 4014) or self._client.close_code == 4004: - raise GatewayException(self._client.close_code) + raise LibraryException(self._client.close_code) await self._handle_connection(stream, shard, presence) diff --git a/interactions/api/http/request.py b/interactions/api/http/request.py index 18cdb3a12..6bbf2e8e5 100644 --- a/interactions/api/http/request.py +++ b/interactions/api/http/request.py @@ -12,7 +12,7 @@ from interactions.base import __version__, get_logger -from ...api.error import HTTPException +from ...api.error import LibraryException from .limiter import Limiter from .route import Route @@ -163,13 +163,15 @@ async def request(self, route: Route, **kwargs) -> Optional[Any]: self.buckets[route.endpoint] = _bucket # real-time replacement/update/add if needed. - if isinstance(data, dict) and data.get("errors"): + if isinstance(data, dict) and ( + data.get("errors") or (data.get("code") and data.get("code") != 429) + ): log.debug( f"RETURN {response.status}: {dumps(data, indent=4, sort_keys=True)}" ) # This "redundant" debug line is for debug use and tracing back the error codes. - raise HTTPException(data["code"], message=data["message"]) + raise LibraryException(message=data["message"], code=data["code"]) if response.status == 429: if not is_global: diff --git a/interactions/api/models/message.py b/interactions/api/models/message.py index 3a3e279ac..72f0ae035 100644 --- a/interactions/api/models/message.py +++ b/interactions/api/models/message.py @@ -4,7 +4,7 @@ from attrs import converters -from ..error import JSONException +from ..error import LibraryException from .attrs_utils import ( MISSING, ClientSerializerMixin, @@ -972,7 +972,7 @@ async def edit( ) if code := _dct.get("code"): - raise JSONException(code, message=_dct.get("message")) + raise LibraryException(code, message=_dct.get("message")) self.update(_dct) diff --git a/interactions/client/bot.py b/interactions/client/bot.py index 672604c0e..1a5951e1d 100644 --- a/interactions/client/bot.py +++ b/interactions/client/bot.py @@ -12,7 +12,7 @@ from ..api import Cache from ..api import Item as Build from ..api import WebSocketClient as WSClient -from ..api.error import InteractionException, JSONException +from ..api.error import LibraryException from ..api.http.client import HTTPClient from ..api.models.attrs_utils import MISSING from ..api.models.flags import Intents, Permissions @@ -403,7 +403,7 @@ async def __get_all_commands(self) -> None: for command in _cmds: if command.get("code"): # Error exists. - raise JSONException(command["code"], message=f'{command["message"]} |') + raise LibraryException(command["code"], message=f'{command["message"]} |') self.__global_commands = {"commands": _cmds, "clean": True} # TODO: add to cache (later) @@ -417,7 +417,7 @@ async def __get_all_commands(self) -> None: if isinstance(_cmds, dict) and _cmds.get("code"): if int(_cmds.get("code")) != 50001: - raise JSONException(_cmds["code"], message=f'{_cmds["message"]} |') + raise LibraryException(_cmds["code"], message=f'{_cmds["message"]} |') log.warning( f"Your bot is missing access to guild with corresponding id {_id}! " @@ -429,7 +429,7 @@ async def __get_all_commands(self) -> None: for command in _cmds: if command.get("code"): # Error exists. - raise JSONException(command["code"], message=f'{command["message"]} |') + raise LibraryException(command["code"], message=f'{command["message"]} |') self.__guild_commands[_id] = {"commands": _cmds, "clean": True} @@ -452,7 +452,7 @@ async def __sync(self) -> None: # sourcery no-metrics for command in _cmds: if command.get("code"): # Error exists. - raise JSONException(command["code"], message=f'{command["message"]} |') + raise LibraryException(command["code"], message=f'{command["message"]} |') self.__global_commands = {"commands": _cmds, "clean": True} # TODO: add to cache (later) @@ -471,7 +471,7 @@ async def __sync(self) -> None: # sourcery no-metrics if isinstance(_cmds, dict) and _cmds.get("code"): # Error exists. if int(_cmds.get("code")) != 50001: - raise JSONException(_cmds["code"], message=f'{_cmds["message"]} |') + raise LibraryException(_cmds["code"], message=f'{_cmds["message"]} |') log.warning( f"Your bot is missing access to guild with corresponding id {_id}! " @@ -485,7 +485,7 @@ async def __sync(self) -> None: # sourcery no-metrics for command in _cmds: if command.get("code"): # Error exists. - raise JSONException(command["code"], message=f'{command["message"]} |') + raise LibraryException(command["code"], message=f'{command["message"]} |') self.__guild_commands[_id] = {"commands": _cmds, "clean": True} __check_guild_commands[_id] = [cmd["name"] for cmd in _cmds] if _cmds else [] @@ -498,7 +498,7 @@ async def __sync(self) -> None: # sourcery no-metrics _guild_id = _guild_command.get("guild_id") if _guild_id in __blocked_guilds: log.fatal(f"Cannot sync commands on guild with id {_guild_id}!") - raise JSONException(50001, message="Missing Access |") + raise LibraryException(50001, message="Missing Access |") if _guild_command["name"] not in __check_guild_commands[_guild_id]: self.__guild_commands[_guild_id]["clean"] = False self.__guild_commands[_guild_id]["commands"].append(_guild_command) @@ -644,27 +644,25 @@ def __check_sub_group(_sub_group: Option): nonlocal _sub_groups_present _sub_groups_present = True if _sub_group.name is MISSING: - raise InteractionException(11, message="Sub command groups must have a name.") + raise LibraryException(11, message="Sub command groups must have a name.") __indent = 4 log.debug( f"{' ' * __indent}checking sub command group '{_sub_group.name}' of command '{command.name}'" ) if not re.fullmatch(reg, _sub_group.name): - raise InteractionException( + raise LibraryException( 11, message=f"The sub command group name does not match the regex for valid names ('{regex}')", ) elif _sub_group.description is MISSING and not _sub_group.description: - raise InteractionException(11, message="A description is required.") + raise LibraryException(11, message="A description is required.") elif len(_sub_group.description) > 100: - raise InteractionException( - 11, message="Descriptions must be less than 100 characters." - ) + raise LibraryException(11, message="Descriptions must be less than 100 characters.") if not _sub_group.options: - raise InteractionException(11, message="sub command groups must have subcommands!") + raise LibraryException(11, message="sub command groups must have subcommands!") if len(_sub_group.options) > 25: - raise InteractionException( + raise LibraryException( 11, message="A sub command group cannot contain more than 25 sub commands!" ) for _sub_command in _sub_group.options: @@ -674,7 +672,7 @@ def __check_sub_command(_sub_command: Option, _sub_group: Option = MISSING): nonlocal _sub_cmds_present _sub_cmds_present = True if _sub_command.name is MISSING: - raise InteractionException(11, message="sub commands must have a name!") + raise LibraryException(11, message="sub commands must have a name!") if _sub_group is not MISSING: __indent = 8 log.debug( @@ -686,20 +684,18 @@ def __check_sub_command(_sub_command: Option, _sub_group: Option = MISSING): f"{' ' * __indent}checking sub command '{_sub_command.name}' of command '{command.name}'" ) if not re.fullmatch(reg, _sub_command.name): - raise InteractionException( + raise LibraryException( 11, message=f"The sub command name does not match the regex for valid names ('{reg}')", ) elif _sub_command.description is MISSING or not _sub_command.description: - raise InteractionException(11, message="A description is required.") + raise LibraryException(11, message="A description is required.") elif len(_sub_command.description) > 100: - raise InteractionException( - 11, message="Descriptions must be less than 100 characters." - ) + raise LibraryException(11, message="Descriptions must be less than 100 characters.") if _sub_command.options is not MISSING and _sub_command.options: if len(_sub_command.options) > 25: - raise InteractionException( + raise LibraryException( 11, message="Your sub command must have less than 25 options." ) _sub_opt_names = [] @@ -712,7 +708,7 @@ def __check_options(_option: Option, _names: list, _sub_command: Option = MISSIN if getattr(_option, "autocomplete", False) and getattr(_option, "choices", False): log.warning("Autocomplete may not be set to true if choices are present.") if _option.name is MISSING: - raise InteractionException(11, message="Options must have a name.") + raise LibraryException(11, message="Options must have a name.") if _sub_command is not MISSING: __indent = 12 if _sub_groups_present else 8 log.debug( @@ -725,22 +721,22 @@ def __check_options(_option: Option, _names: list, _sub_command: Option = MISSIN ) _options_names.append(_option.name) if not re.fullmatch(reg, _option.name): - raise InteractionException( + raise LibraryException( 11, message=f"The option name does not match the regex for valid names ('{regex}')", ) if _option.description is MISSING or not _option.description: - raise InteractionException( + raise LibraryException( 11, message="A description is required.", ) elif len(_option.description) > 100: - raise InteractionException( + raise LibraryException( 11, message="Descriptions must be less than 100 characters.", ) if _option.name in _names: - raise InteractionException( + raise LibraryException( 11, message="You must not have two options with the same name in a command!" ) _names.append(_option.name) @@ -752,17 +748,17 @@ def __check_coro(): if not len(coro.__code__.co_varnames) ^ ( _ismethod and len(coro.__code__.co_varnames) == 1 ): - raise InteractionException( + raise LibraryException( 11, message="Your command needs at least one argument to return context." ) elif "kwargs" in coro.__code__.co_varnames: return elif _sub_cmds_present and len(coro.__code__.co_varnames) < (3 if _ismethod else 2): - raise InteractionException( + raise LibraryException( 11, message="Your command needs one argument for the sub_command." ) elif _sub_groups_present and len(coro.__code__.co_varnames) < (4 if _ismethod else 3): - raise InteractionException( + raise LibraryException( 11, message="Your command needs one argument for the sub_command and one for the sub_command_group.", ) @@ -775,12 +771,12 @@ def __check_coro(): "Coroutine is missing arguments for options:" f" {[_arg for _arg in _options_names if _arg not in coro.__code__.co_varnames]}" ) - raise InteractionException( + raise LibraryException( 11, message="You need one argument for every option name in your command!" ) if command.name is MISSING: - raise InteractionException(11, message="Your command must have a name.") + raise LibraryException(11, message="Your command must have a name.") else: log.debug(f"checking command '{command.name}':") @@ -788,31 +784,27 @@ def __check_coro(): not re.fullmatch(reg, command.name) and command.type == ApplicationCommandType.CHAT_INPUT ): - raise InteractionException( + raise LibraryException( 11, message=f"Your command does not match the regex for valid names ('{regex}')" ) elif command.type == ApplicationCommandType.CHAT_INPUT and ( command.description is MISSING or not command.description ): - raise InteractionException(11, message="A description is required.") + raise LibraryException(11, message="A description is required.") elif command.type != ApplicationCommandType.CHAT_INPUT and ( command.description is not MISSING and command.description ): - raise InteractionException( - 11, message="Only chat-input commands can have a description." - ) + raise LibraryException(11, message="Only chat-input commands can have a description.") elif command.description is not MISSING and len(command.description) > 100: - raise InteractionException(11, message="Descriptions must be less than 100 characters.") + raise LibraryException(11, message="Descriptions must be less than 100 characters.") if command.options and command.options is not MISSING: if len(command.options) > 25: - raise InteractionException( - 11, message="Your command must have less than 25 options." - ) + raise LibraryException(11, message="Your command must have less than 25 options.") if command.type != ApplicationCommandType.CHAT_INPUT: - raise InteractionException( + raise LibraryException( 11, message="Only CHAT_INPUT commands can have options/sub-commands!" ) @@ -1167,7 +1159,7 @@ def _find_command(self, command: str) -> ApplicationCommand: break if not _command_obj or (hasattr(_command_obj, "id") and not _command_obj.id): - raise InteractionException( + raise LibraryException( 6, message="The command does not exist. Make sure to define" + " your autocomplete callback after your commands", diff --git a/interactions/client/context.py b/interactions/client/context.py index 3026f2079..c183eec78 100644 --- a/interactions/client/context.py +++ b/interactions/client/context.py @@ -1,7 +1,7 @@ from logging import Logger from typing import List, Optional, Union -from ..api import InteractionException +from ..api.error import LibraryException from ..api.models.attrs_utils import MISSING, DictSerializerMixin, define, field from ..api.models.channel import Channel from ..api.models.guild import Guild @@ -483,7 +483,7 @@ async def func(): ): _choices = list(choices) else: - raise InteractionException( + raise LibraryException( 6, message="Autocomplete choice items must be of type Choice" ) diff --git a/interactions/client/models/component.py b/interactions/client/models/component.py index e0e04a3ff..9e7553ad8 100644 --- a/interactions/client/models/component.py +++ b/interactions/client/models/component.py @@ -1,6 +1,6 @@ from typing import List, Optional -from ...api.error import InteractionException +from ...api.error import LibraryException from ...api.models.attrs_utils import MISSING, DictSerializerMixin, convert_list, define, field from ...api.models.message import Emoji from ..enums import ButtonStyle, ComponentType, TextStyleType @@ -395,7 +395,7 @@ def __check_components(): ) return _components else: - raise InteractionException( + raise LibraryException( 11, message="The specified components are invalid and could not be created!" )