diff --git a/arc/client.py b/arc/client.py index f097e11..c646b5f 100644 --- a/arc/client.py +++ b/arc/client.py @@ -1,6 +1,7 @@ from __future__ import annotations import abc +import asyncio import functools import importlib import inspect @@ -16,7 +17,7 @@ from .command import MessageCommand, SlashCommand, SlashGroup, SlashSubCommand, SlashSubGroup, UserCommand from .context import AutodeferMode, Context -from .errors import ExtensionLoadError, ExtensionUnloadError +from .errors import ExtensionLoadError, ExtensionUnloadError, NoResponseIssuedError from .events import CommandErrorEvent from .internal.sync import _sync_commands from .internal.types import AppT, BuilderT, EventCallbackT, EventT, ResponseBuilderT @@ -257,8 +258,16 @@ async def on_command_interaction(self, interaction: hikari.CommandInteraction) - fut = await command.invoke(interaction) - if fut is not None: - return await fut + if fut is None: + return + + try: + return await asyncio.wait_for(fut, timeout=3.0) + except asyncio.TimeoutError: + logger.warning( + f"Timed out waiting for response from command: '{interaction.command_name} ({interaction.command_type})'" + f" Did you forget to respond?" + ) async def on_autocomplete_interaction( self, interaction: hikari.AutocompleteInteraction @@ -869,14 +878,20 @@ async def on_restbot_shutdown(self, bot: hikari.RESTBotAware) -> None: async def _on_restbot_interaction_create(self, interaction: hikari.CommandInteraction) -> ResponseBuilderT: builder = await self.on_command_interaction(interaction) - assert builder is not None + if builder is None: + raise NoResponseIssuedError( + f"No response was issued to interaction for command: {interaction.command_name} ({interaction.command_type})." + ) return builder async def _on_restbot_autocomplete_interaction_create( self, interaction: hikari.AutocompleteInteraction ) -> hikari.api.InteractionAutocompleteBuilder: builder = await self.on_autocomplete_interaction(interaction) - assert builder is not None + if builder is None: + raise NoResponseIssuedError( + f"No response was issued to autocomplete request for command: {interaction.command_name} ({interaction.command_type})." + ) return builder diff --git a/arc/errors.py b/arc/errors.py index 6711558..0c747e3 100644 --- a/arc/errors.py +++ b/arc/errors.py @@ -1,4 +1,12 @@ -__all__ = ("ArcError", "AutocompleteError", "CommandInvokeError") +__all__ = ( + "ArcError", + "AutocompleteError", + "CommandInvokeError", + "ExtensionError", + "ExtensionLoadError", + "ExtensionUnloadError", + "NoResponseIssuedError", +) class ArcError(Exception): @@ -25,6 +33,14 @@ class ExtensionUnloadError(ExtensionError): """An error occurred while trying to unload an extension.""" +class NoResponseIssuedError(ArcError): + """Raised when no response was issued by a command. + Interactions must be responded to or deferred within 3 seconds to avoid this error. + + `arc` tries to automatically defer responses when possible, so this error should rarely occur, unless autodefer is disabled. + """ + + # MIT License # # Copyright (c) 2023-present hypergonial diff --git a/docs/changelog.md b/docs/changelog.md index 5833143..74fb303 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -9,6 +9,10 @@ hide: Here you can find all the changelogs for `hikari-arc`. +## v0.1.4 + +- Improve handling missing responses via REST by adding `NoResponseIssuedError`. + ## v0.1.3 - Fix `Context.respond_with_builder` issuing the response twice in REST.