[V3] Send meaningful responses on conversion failure (#1817)

* [V3] Send meaningful responses on conversion failures

* Replace existing `discord.ext.commands` imports

Just to be sure

* Better Permissions converter response
This commit is contained in:
Tobotimus 2018-06-09 11:20:40 +10:00 committed by Will
parent d0a53ed2df
commit 033d0113a5
15 changed files with 82 additions and 26 deletions

View File

@ -1,9 +1,8 @@
from typing import Tuple
import discord
from discord.ext import commands
from redbot.core import Config, checks
from redbot.core import Config, checks, commands
import logging

View File

@ -1,7 +1,7 @@
import asyncio
import discord
from discord.ext import commands
from redbot.core import commands
class Announcer:

View File

@ -1,5 +1,5 @@
import discord
from discord.ext import commands
from redbot.core import commands
class MemberDefaultAuthor(commands.Converter):

View File

@ -1,6 +1,6 @@
from .alias import Alias
from discord.ext import commands
from redbot.core.bot import Red
def setup(bot: commands.Bot):
def setup(bot: Red):
bot.add_cog(Alias(bot))

View File

@ -5,7 +5,7 @@ import logging
from .audio import Audio
from .manager import start_lavalink_server
from discord.ext import commands
from redbot.core import commands
from redbot.core.data_manager import cog_data_path
import redbot.core

View File

@ -1,6 +1,5 @@
import discord
from discord.ext import commands
from .repo_manager import RepoManager
from redbot.core import commands
from .installable import Installable

View File

@ -2,17 +2,13 @@ import asyncio
import functools
import os
import pkgutil
import shutil
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
from subprocess import run as sp_run, PIPE
from sys import executable
from typing import Tuple, MutableMapping, Union
from discord.ext import commands
from redbot.core import Config
from redbot.core import data_manager
from redbot.core import data_manager, commands
from redbot.core.utils import safe_delete
from .errors import *
from .installable import Installable, InstallableType
@ -232,7 +228,7 @@ class Repo(RepoJSONMixin):
----------
branch : `str`, optional
Override for repo's branch attribute.
Returns
-------
str
@ -381,7 +377,7 @@ class Repo(RepoJSONMixin):
Directory to install shared libraries to.
libraries : `tuple` of `Installable`
A subset of available libraries.
Returns
-------
bool
@ -403,7 +399,7 @@ class Repo(RepoJSONMixin):
async def install_requirements(self, cog: Installable, target_dir: Path) -> bool:
"""Install a cog's requirements.
Requirements will be installed via pip directly into
:code:`target_dir`.
@ -465,7 +461,7 @@ class Repo(RepoJSONMixin):
@property
def available_cogs(self) -> Tuple[Installable]:
"""`tuple` of `installable` : All available cogs in this Repo.
This excludes hidden or shared packages.
"""
# noinspection PyTypeChecker

View File

@ -1,4 +1,4 @@
from discord.ext import commands
from redbot.core import commands
import discord

View File

@ -11,7 +11,10 @@ class CogOrCommand(commands.Converter):
if ret:
return "commands", ret.qualified_name
raise commands.BadArgument()
raise commands.BadArgument(
'Cog or command "{arg}" not found. Please note that this is case sensitive.'
"".format(arg=arg)
)
class RuleType(commands.Converter):
@ -21,4 +24,6 @@ class RuleType(commands.Converter):
if arg.lower() in ("deny", "blacklist", "denied"):
return "deny"
raise commands.BadArgument()
raise commands.BadArgument(
'"{arg}" is not a valid rule. Valid rules are "allow" or "deny"'.format(arg=arg)
)

View File

@ -2,7 +2,7 @@
from collections import Counter
import yaml
import discord
from discord.ext import commands
from redbot.core import commands
from redbot.ext import trivia as ext_trivia
from redbot.core import Config, checks
from redbot.core.data_manager import cog_data_path

View File

@ -1,5 +1,5 @@
import discord
from discord.ext import commands
from redbot.core import commands
async def check_overrides(ctx, *, level):

View File

@ -2,3 +2,4 @@
from discord.ext.commands import *
from .commands import *
from .context import *
from .errors import *

View File

@ -4,12 +4,20 @@ This module contains extended classes and functions which are intended to
replace those from the `discord.ext.commands` module.
"""
import inspect
from typing import TYPE_CHECKING
from discord.ext import commands
from .errors import ConversionFailure
from ..i18n import Translator
if TYPE_CHECKING:
from .context import Context
__all__ = ["Command", "Group", "command", "group"]
_ = Translator("commands.commands", __file__)
class Command(commands.Command):
"""Command class for Red.
@ -53,7 +61,7 @@ class Command(commands.Command):
"""
Returns all parent commands of this command.
This is a list, sorted by the length of :attr:`.qualified_name` from highest to lowest.
This is a list, sorted by the length of :attr:`.qualified_name` from highest to lowest.
If the command has no parents, this will be an empty list.
"""
cmd = self.parent
@ -63,6 +71,37 @@ class Command(commands.Command):
cmd = cmd.parent
return sorted(entries, key=lambda x: len(x.qualified_name), reverse=True)
async def do_conversion(self, ctx: "Context", converter, argument: str):
"""Convert an argument according to its type annotation.
Raises
------
ConversionFailure
If doing the conversion failed.
Returns
-------
Any
The converted argument.
"""
# Let's not worry about all of this junk if it's just a str converter
if converter is str:
return argument
try:
return await super().do_conversion(ctx, converter, argument)
except commands.BadArgument as exc:
raise ConversionFailure(converter, argument, *exc.args) from exc
except ValueError as exc:
# Some common converters need special treatment...
if converter in (int, float):
message = _('"{argument}" is not a number.').format(argument=argument)
raise ConversionFailure(converter, argument, message) from exc
# We should expose anything which might be a bug in the converter
raise exc
def command(self, cls=None, *args, **kwargs):
"""A shortcut decorator that invokes :func:`.command` and adds it to
the internal command list via :meth:`~.GroupMixin.add_command`.

View File

@ -0,0 +1,13 @@
"""Errors module for the commands package."""
from discord.ext import commands
__all__ = ["ConversionFailure"]
class ConversionFailure(commands.BadArgument):
"""Raised when converting an argument fails."""
def __init__(self, converter, argument: str, *args):
self.converter = converter
self.argument = argument
super().__init__(*args)

View File

@ -11,9 +11,8 @@ from pkg_resources import DistributionNotFound
import discord
from discord.ext import commands
from . import __version__
from . import __version__, commands
from .data_manager import storage_type
from .utils.chat_formatting import inline, bordered, pagify, box
from .utils import fuzzy_command_search
@ -185,6 +184,11 @@ def init_events(bot, cli_flags):
async def on_command_error(ctx, error):
if isinstance(error, commands.MissingRequiredArgument):
await ctx.send_help()
elif isinstance(error, commands.ConversionFailure):
if error.args:
await ctx.send(error.args[0])
else:
await ctx.send_help()
elif isinstance(error, commands.BadArgument):
await ctx.send_help()
elif isinstance(error, commands.DisabledCommand):