diff --git a/discord/ext/commands/errors.py b/discord/ext/commands/errors.py index 1a912b2e9..2b74a3f0f 100644 --- a/discord/ext/commands/errors.py +++ b/discord/ext/commands/errors.py @@ -1138,15 +1138,23 @@ class BadFlagArgument(FlagError): ----------- flag: :class:`~discord.ext.commands.Flag` The flag that failed to convert. + argument: :class:`str` + The argument supplied by the caller that was not able to be converted. + original: :class:`Exception` + The original exception that was raised. You can also get this via + the ``__cause__`` attribute. """ - def __init__(self, flag: Flag) -> None: + def __init__(self, flag: Flag, argument: str, original: Exception) -> None: self.flag: Flag = flag try: name = flag.annotation.__name__ except AttributeError: name = flag.annotation.__class__.__name__ + self.argument: str = argument + self.original: Exception = original + super().__init__(f'Could not convert to {name!r} for flag {flag.name!r}') diff --git a/discord/ext/commands/flags.py b/discord/ext/commands/flags.py index 8c63bcfde..e66d238cf 100644 --- a/discord/ext/commands/flags.py +++ b/discord/ext/commands/flags.py @@ -33,7 +33,7 @@ from typing import TYPE_CHECKING, Any, Dict, Iterator, List, Literal, Optional, from discord.utils import MISSING, maybe_coroutine, resolve_annotation from .converter import run_converters -from .errors import BadFlagArgument, CommandError, MissingFlagArgument, MissingRequiredFlag, TooManyFlags +from .errors import BadFlagArgument, MissingFlagArgument, MissingRequiredFlag, TooManyFlags from .view import StringView __all__ = ( @@ -368,10 +368,8 @@ async def tuple_convert_all(ctx: Context[BotT], argument: str, flag: Flag, conve try: converted = await run_converters(ctx, converter, word, param) - except CommandError: - raise except Exception as e: - raise BadFlagArgument(flag) from e + raise BadFlagArgument(flag, word, e) from e else: results.append(converted) @@ -393,15 +391,13 @@ async def tuple_convert_flag(ctx: Context[BotT], argument: str, flag: Flag, conv try: converted = await run_converters(ctx, converter, word, param) - except CommandError: - raise except Exception as e: - raise BadFlagArgument(flag) from e + raise BadFlagArgument(flag, word, e) from e else: results.append(converted) if len(results) != len(converters): - raise BadFlagArgument(flag) + raise MissingFlagArgument(flag) return tuple(results) @@ -433,10 +429,8 @@ async def convert_flag(ctx: Context[BotT], argument: str, flag: Flag, annotation try: return await run_converters(ctx, annotation, argument, param) - except CommandError: - raise except Exception as e: - raise BadFlagArgument(flag) from e + raise BadFlagArgument(flag, argument, e) from e class FlagConverter(metaclass=FlagsMeta): @@ -559,8 +553,6 @@ class FlagConverter(metaclass=FlagsMeta): Parameters ---------- - cls: Type[:class:`FlagConverter`] - The flag converter class. ctx: :class:`Context` The invocation context. argument: :class:`str` @@ -570,8 +562,6 @@ class FlagConverter(metaclass=FlagsMeta): -------- FlagError A flag related parsing error. - CommandError - A command related error. Returns -------- diff --git a/docs/ext/commands/commands.rst b/docs/ext/commands/commands.rst index eec8f5099..b636b554f 100644 --- a/docs/ext/commands/commands.rst +++ b/docs/ext/commands/commands.rst @@ -798,6 +798,10 @@ In order to customise the flag syntax we also have a few options that can be pas a command line parser. The syntax is mainly inspired by Discord's search bar input and as a result all flags need a corresponding value. +Flag converters will only raise :exc:`~ext.commands.FlagError` derived exceptions. If an error is raised while +converting a flag, :exc:`~ext.commands.BadFlagArgument` is raised instead and the original exception +can be accessed with the :attr:`~ext.commands.BadFlagArgument.original` attribute. + The flag converter is similar to regular commands and allows you to use most types of converters (with the exception of :class:`~ext.commands.Greedy`) as the type annotation. Some extra support is added for specific annotations as described below.