Discord.py discord.NotFound exception

2019-07-12 19:46发布

问题:

everyone. I've been working on a few bots for my discord server and I've come across an issue in one of them which I cant seem to solve. I have a command called 'info', essentially, this command displays some information on a desired user. When I call the command ?info [user], it works just fine until I intentionally request the info on a user that doesn't exist to test an exception I have in place. Here'

@laugh.command(pass_context=True)
async def info(ctx, user: discord.Member = None):
    if ctx.message.channel.name != "admin":
        await laugh.send_message(ctx.message.author, "Sorry, you need to be in a text channel called 'admin' for that.")
        return
    if not ctx.message.author.server_permissions.administrator:
        return
    if not user:
        user = ctx.message.author
    try:
        minfo = ("""
{0}'s ID is: {1}
{0}'s status is: {2}
{0}'s highest role is: {3}
{0} joined at: {4}""".format(user.name, user.id, user.status, user.top_role, user.joined_at))
        embed = discord.Embed(title = user.name, description = minfo, color = 0x00D2FF)
        await laugh.say(embed = embed)
    except discord.NotFound:
        await laugh.say("User not found.")

When I run this code and give a non-existent user as parameters, my exception doesn't work, instead, I get this output to my console:

Ignoring exception in command info
Traceback (most recent call last):
  File "C:\Users\Matthew\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\bot.py", line 846, in process_commands
    yield from command.invoke(ctx)
  File "C:\Users\Matthew\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 367, in invoke
    yield from self.prepare(ctx)
  File "C:\Users\Matthew\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 345, in prepare
    yield from self._parse_arguments(ctx)
  File "C:\Users\Matthew\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 304, in _parse_arguments
    transformed = yield from self.transform(ctx, param)
  File "C:\Users\Matthew\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 223, in transform
    raise e
  File "C:\Users\Matthew\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 221, in transform
    return (yield from self.do_conversion(ctx, converter, argument))
  File "C:\Users\Matthew\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 184, in do_conversion
    return instance.convert()
  File "C:\Users\Matthew\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\converter.py", line 100, in convert
    raise BadArgument('Member "{}" not found'.format(self.argument))
discord.ext.commands.errors.BadArgument: Member "test" not found

I've looked at countless examples and forums posts and the only knowledge I've gained was that the source of the error is in async def info(ctx, user: discord.Member = None):, any ideas on what I can do?

回答1:

Error handling for commands is a little weird. When you specify a converter for the argument user, that conversion takes place outside of the body of the command coroutine. To handle it, you must write an error handler coroutine, and associate it with the command in question.

@laugh.command(pass_context=True)
async def info(ctx, user: discord.Member = None):
    if ctx.message.channel.name != "admin":
        await laugh.send_message(ctx.message.author, "Sorry, you need to be in a text channel called 'admin' for that.")
        return
    if not ctx.message.author.server_permissions.administrator:
        return
    if not user:
        user = ctx.message.author
    minfo = ("""
{0}'s ID is: {1}
{0}'s status is: {2}
{0}'s highest role is: {3}
{0} joined at: {4}""".format(user.name, user.id, user.status, user.top_role, user.joined_at))
    embed = discord.Embed(title = user.name, description = minfo, color = 0x00D2FF)
    await laugh.say(embed = embed)

@info.error
async def info_error(ctx, error): # This might need to be (error, ctx), I'm not sure
    if isinstance(error, commands.BadArgument):
        await laugh.say('I could not find that user')

You can read the documentation for error handlers, and the rest of the discord.ext.commands module, in the documentation for the rewrite branch.

If you're going to be doing a lot of work with the commands extension, it may make sense to convert your code now so that you can work with accurate documentation.