[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 from typing import Tuple
import discord import discord
from discord.ext import commands
from redbot.core import Config, checks from redbot.core import Config, checks, commands
import logging import logging

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
from .alias import Alias 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)) bot.add_cog(Alias(bot))

View File

@@ -5,7 +5,7 @@ import logging
from .audio import Audio from .audio import Audio
from .manager import start_lavalink_server 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 from redbot.core.data_manager import cog_data_path
import redbot.core import redbot.core

View File

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

View File

@@ -2,17 +2,13 @@ import asyncio
import functools import functools
import os import os
import pkgutil import pkgutil
import shutil
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
from pathlib import Path from pathlib import Path
from subprocess import run as sp_run, PIPE from subprocess import run as sp_run, PIPE
from sys import executable from sys import executable
from typing import Tuple, MutableMapping, Union from typing import Tuple, MutableMapping, Union
from discord.ext import commands from redbot.core import data_manager, commands
from redbot.core import Config
from redbot.core import data_manager
from redbot.core.utils import safe_delete from redbot.core.utils import safe_delete
from .errors import * from .errors import *
from .installable import Installable, InstallableType from .installable import Installable, InstallableType

View File

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

View File

@@ -11,7 +11,10 @@ class CogOrCommand(commands.Converter):
if ret: if ret:
return "commands", ret.qualified_name 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): class RuleType(commands.Converter):
@@ -21,4 +24,6 @@ class RuleType(commands.Converter):
if arg.lower() in ("deny", "blacklist", "denied"): if arg.lower() in ("deny", "blacklist", "denied"):
return "deny" 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 from collections import Counter
import yaml import yaml
import discord import discord
from discord.ext import commands from redbot.core import commands
from redbot.ext import trivia as ext_trivia from redbot.ext import trivia as ext_trivia
from redbot.core import Config, checks from redbot.core import Config, checks
from redbot.core.data_manager import cog_data_path from redbot.core.data_manager import cog_data_path

View File

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

View File

@@ -2,3 +2,4 @@
from discord.ext.commands import * from discord.ext.commands import *
from .commands import * from .commands import *
from .context 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. replace those from the `discord.ext.commands` module.
""" """
import inspect import inspect
from typing import TYPE_CHECKING
from discord.ext import commands 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"] __all__ = ["Command", "Group", "command", "group"]
_ = Translator("commands.commands", __file__)
class Command(commands.Command): class Command(commands.Command):
"""Command class for Red. """Command class for Red.
@@ -63,6 +71,37 @@ class Command(commands.Command):
cmd = cmd.parent cmd = cmd.parent
return sorted(entries, key=lambda x: len(x.qualified_name), reverse=True) 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): def command(self, cls=None, *args, **kwargs):
"""A shortcut decorator that invokes :func:`.command` and adds it to """A shortcut decorator that invokes :func:`.command` and adds it to
the internal command list via :meth:`~.GroupMixin.add_command`. 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 import discord
from discord.ext import commands
from . import __version__ from . import __version__, commands
from .data_manager import storage_type from .data_manager import storage_type
from .utils.chat_formatting import inline, bordered, pagify, box from .utils.chat_formatting import inline, bordered, pagify, box
from .utils import fuzzy_command_search from .utils import fuzzy_command_search
@@ -185,6 +184,11 @@ def init_events(bot, cli_flags):
async def on_command_error(ctx, error): async def on_command_error(ctx, error):
if isinstance(error, commands.MissingRequiredArgument): if isinstance(error, commands.MissingRequiredArgument):
await ctx.send_help() 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): elif isinstance(error, commands.BadArgument):
await ctx.send_help() await ctx.send_help()
elif isinstance(error, commands.DisabledCommand): elif isinstance(error, commands.DisabledCommand):