mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-05-11 16:29:49 +00:00
[commands] Add cog-level app command error special method
This commit is contained in:
parent
2067819b75
commit
0546343bcb
@ -598,7 +598,7 @@ class Command(Generic[GroupT, P, T]):
|
|||||||
|
|
||||||
return base
|
return base
|
||||||
|
|
||||||
async def _invoke_error_handler(self, interaction: Interaction, error: AppCommandError) -> None:
|
async def _invoke_error_handlers(self, interaction: Interaction, error: AppCommandError) -> None:
|
||||||
# These type ignores are because the type checker can't narrow this type properly.
|
# These type ignores are because the type checker can't narrow this type properly.
|
||||||
if self.on_error is not None:
|
if self.on_error is not None:
|
||||||
if self.binding is not None:
|
if self.binding is not None:
|
||||||
@ -613,6 +613,10 @@ class Command(Generic[GroupT, P, T]):
|
|||||||
if parent.parent is not None:
|
if parent.parent is not None:
|
||||||
await parent.parent.on_error(interaction, error)
|
await parent.parent.on_error(interaction, error)
|
||||||
|
|
||||||
|
cog_error = getattr(self.binding, '__app_commands_error_handler__', None)
|
||||||
|
if cog_error is not None:
|
||||||
|
await cog_error(interaction, error)
|
||||||
|
|
||||||
def _has_any_error_handlers(self) -> bool:
|
def _has_any_error_handlers(self) -> bool:
|
||||||
if self.on_error is not None:
|
if self.on_error is not None:
|
||||||
return True
|
return True
|
||||||
|
@ -992,12 +992,19 @@ class CommandTree(Generic[ClientT]):
|
|||||||
|
|
||||||
return [AppCommand(data=d, state=self._state) for d in data]
|
return [AppCommand(data=d, state=self._state) for d in data]
|
||||||
|
|
||||||
def _from_interaction(self, interaction: Interaction):
|
async def _dispatch_error(self, interaction: Interaction, error: AppCommandError, /) -> None:
|
||||||
|
command = interaction.command
|
||||||
|
if isinstance(command, Command):
|
||||||
|
await command._invoke_error_handlers(interaction, error)
|
||||||
|
else:
|
||||||
|
await self.on_error(interaction, error)
|
||||||
|
|
||||||
|
def _from_interaction(self, interaction: Interaction) -> None:
|
||||||
async def wrapper():
|
async def wrapper():
|
||||||
try:
|
try:
|
||||||
await self.call(interaction)
|
await self.call(interaction)
|
||||||
except AppCommandError as e:
|
except AppCommandError as e:
|
||||||
await self.on_error(interaction, e)
|
await self._dispatch_error(interaction, e)
|
||||||
|
|
||||||
self.client.loop.create_task(wrapper(), name='CommandTree-invoker')
|
self.client.loop.create_task(wrapper(), name='CommandTree-invoker')
|
||||||
|
|
||||||
@ -1167,5 +1174,5 @@ class CommandTree(Generic[ClientT]):
|
|||||||
try:
|
try:
|
||||||
await command._invoke_with_namespace(interaction, namespace)
|
await command._invoke_with_namespace(interaction, namespace)
|
||||||
except AppCommandError as e:
|
except AppCommandError as e:
|
||||||
await command._invoke_error_handler(interaction, e)
|
await command._invoke_error_handlers(interaction, e)
|
||||||
await self.on_error(interaction, e)
|
await self.on_error(interaction, e)
|
||||||
|
@ -28,7 +28,21 @@ import discord
|
|||||||
from discord import app_commands
|
from discord import app_commands
|
||||||
from discord.utils import maybe_coroutine
|
from discord.utils import maybe_coroutine
|
||||||
|
|
||||||
from typing import Any, Callable, ClassVar, Dict, Generator, Iterable, List, Optional, TYPE_CHECKING, Tuple, TypeVar, Union
|
from typing import (
|
||||||
|
Any,
|
||||||
|
Callable,
|
||||||
|
ClassVar,
|
||||||
|
Coroutine,
|
||||||
|
Dict,
|
||||||
|
Generator,
|
||||||
|
Iterable,
|
||||||
|
List,
|
||||||
|
Optional,
|
||||||
|
TYPE_CHECKING,
|
||||||
|
Tuple,
|
||||||
|
TypeVar,
|
||||||
|
Union,
|
||||||
|
)
|
||||||
|
|
||||||
from ._types import _BaseCommand, BotT
|
from ._types import _BaseCommand, BotT
|
||||||
|
|
||||||
@ -254,6 +268,9 @@ class Cog(metaclass=CogMeta):
|
|||||||
__cog_listeners__: List[Tuple[str, str]]
|
__cog_listeners__: List[Tuple[str, str]]
|
||||||
__cog_is_app_commands_group__: ClassVar[bool] = False
|
__cog_is_app_commands_group__: ClassVar[bool] = False
|
||||||
__cog_app_commands_group__: Optional[app_commands.Group]
|
__cog_app_commands_group__: Optional[app_commands.Group]
|
||||||
|
__app_commands_error_handler__: Optional[
|
||||||
|
Callable[[discord.Interaction, app_commands.AppCommandError], Coroutine[Any, Any, None]]
|
||||||
|
]
|
||||||
|
|
||||||
def __new__(cls, *args: Any, **kwargs: Any) -> Self:
|
def __new__(cls, *args: Any, **kwargs: Any) -> Self:
|
||||||
# For issue 426, we need to store a copy of the command objects
|
# For issue 426, we need to store a copy of the command objects
|
||||||
@ -329,6 +346,11 @@ class Cog(metaclass=CogMeta):
|
|||||||
|
|
||||||
self.__cog_app_commands_group__._children = mapping # type: ignore # Variance issue
|
self.__cog_app_commands_group__._children = mapping # type: ignore # Variance issue
|
||||||
|
|
||||||
|
if Cog._get_overridden_method(self.cog_app_command_error) is not None:
|
||||||
|
self.__app_commands_error_handler__ = self.cog_app_command_error
|
||||||
|
else:
|
||||||
|
self.__app_commands_error_handler__ = None
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def get_commands(self) -> List[Command[Self, ..., Any]]:
|
def get_commands(self) -> List[Command[Self, ..., Any]]:
|
||||||
@ -524,6 +546,25 @@ class Cog(metaclass=CogMeta):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@_cog_special_method
|
||||||
|
async def cog_app_command_error(self, interaction: discord.Interaction, error: app_commands.AppCommandError) -> None:
|
||||||
|
"""A special method that is called whenever an error within
|
||||||
|
an application command is dispatched inside this cog.
|
||||||
|
|
||||||
|
This is similar to :func:`discord.app_commands.CommandTree.on_error` except
|
||||||
|
only applying to the application commands inside this cog.
|
||||||
|
|
||||||
|
This **must** be a coroutine.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
interaction: :class:`~discord.Interaction`
|
||||||
|
The interaction that is being handled.
|
||||||
|
error: :exc:`~discord.app_commands.AppCommandError`
|
||||||
|
The exception that was raised.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
@_cog_special_method
|
@_cog_special_method
|
||||||
async def cog_before_invoke(self, ctx: Context[BotT]) -> None:
|
async def cog_before_invoke(self, ctx: Context[BotT]) -> None:
|
||||||
"""A special method that acts as a cog local pre-invoke hook.
|
"""A special method that acts as a cog local pre-invoke hook.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user