Search code examples
pythondiscorddiscord.py

Discord.py I want to have ,open as the command for this but it gives an error


I'm working on creating a economy bot on Discord but whenever my command is ,create it works fine but when I try change the commands name to ,open it gives me this error

The Error:

/home/runner/w/main.py:13: RuntimeWarning: coroutine 'Command.__call__' was never awaited
  with open('user_accounts.json', 'w') as f:
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
2024-02-20 23:51:22 ERROR    discord.ext.commands.bot Ignoring exception in command open
Traceback (most recent call last):
  File "/home/runner/w/.pythonlibs/lib/python3.10/site-packages/discord/ext/commands/core.py", line 235, in wrapped
    ret = await coro(*args, **kwargs)
  File "/home/runner/w/main.py", line 33, in open
    save_accounts()
  File "/home/runner/w/main.py", line 13, in save_accounts
    with open('user_accounts.json', 'w') as f:
AttributeError: __enter__

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/runner/w/.pythonlibs/lib/python3.10/site-packages/discord/ext/commands/bot.py", line 1350, in invoke
    await ctx.command.invoke(ctx)
  File "/home/runner/w/.pythonlibs/lib/python3.10/site-packages/discord/ext/commands/core.py", line 1029, in invoke
    await injected(*ctx.args, **ctx.kwargs)  # type: ignore
  File "/home/runner/w/.pythonlibs/lib/python3.10/site-packages/discord/ext/commands/core.py", line 244, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: __enter__

My Code:

def save_accounts():
    with open('user_accounts.json', 'w') as f:
        json.dump(user_accounts, f, indent=4)

try:
    with open('user_accounts.json', 'r') as f:
        user_accounts = json.load(f)
except FileNotFoundError:
    user_accounts = {}

@bot.event
async def on_ready():
    print(f'{bot.user.name} is online')

@bot.command()
async def open(ctx):
    user_id = str(ctx.author.id)
    if user_id not in user_accounts:
        user_accounts[user_id] = {'balance': 15}
        await ctx.send('Account created successfully!')
        save_accounts()
    else:
        await ctx.send('You already have an account.')

I've tried making the command name ,create and it works fine but I need it to be ,open


Solution

  • By using the with keyword, you are triggering the __enter__ method.

    The error; coroutine was never awaited, tells us that there is an asynchronous function that was ran without the await keyword.

    But where is the problem in the code?

    Well, you have actually reassigned the built-in open function as your command callback. And is not awaited in with open(), throwing the error. To fix this while maintaining the command name, we can assign the name of the command in the decorator.

    @bot.command(name="open")
    async def open_command(ctx):
        ...
    

    To avoid this error, make sure that you are not redefining any built-in functions like open.

    Documentation: @bot.command