@Miron232

Вылезает ошибка discord.ext.commands.errors.CommandInvokeError: Command raised an exception: KeyError: 1189988964807999659?

Пишу дискорд-бота на Python 3.12.1 Visual Studio Code
Вот код:

import discord
from discord.ext import commands

intents = discord.Intents.default()
intents.messages = True

intents = discord.Intents().all()
bot = commands.Bot(command_prefix='!', intents=intents)

@bot.event
async def on_ready():
    print('Bot is ready')

@bot.command()
async def messages(ctx):
    user_messages = {}
    for channel in ctx.guild.text_channels:
        async for message in channel.history(limit=None):
            if message.author.id not in user_messages:
                user_messages[message.author.id] = 1
            else:
                user_messages[message.author.id] += 1
            
    sorted_users = sorted(user_messages.items(), key=lambda x: x[1], reverse=True)
    for i, (user_id, message_count) in enumerate(sorted_users):
        if user_id == ctx.author.id:
            await ctx.send(f'{message.author.name} Вы отправили {message_count} сообщений на сервере и занимаете {i+1} место в рейтинге')
            break



initial_balance = 200
user_balances = {}


@bot.command()
async def balance(ctx):
    user = ctx.author
    balance = user_balances.get(user.id, initial_balance)
    await ctx.send(f'Your balance is {balance} tokens.')

@bot.command()
async def pay(ctx, recipient: discord.Member, amount: int):
    author = ctx.author
    if user_balances.get(author.id, initial_balance) < amount:
        await ctx.send('Insufficient funds.')
    else:
        user_balances[author.id] -= amount
        user_balances[recipient.id] = user_balances.get(recipient.id, initial_balance) + amount
        await ctx.send(f'Successfully paid {amount} tokens to {recipient.display_name}.')

@bot.command()
async def casino(ctx, amount: int):
    user = ctx.author
    if user_balances.get(user.id, initial_balance) < amount:
        await ctx.send('Insufficient funds.')
    else:
        import random
        result = random.choice([-1, 1])
        user_balances[user.id] += result * amount
        if result == 1:
            await ctx.send(f'Congratulations, you won {amount} tokens!')
        else:
            await ctx.send(f'Unlucky, you lost {amount} tokens.')

bot.run("MTIzODg2NDU2NzE5NTY2NDM4NQ.G8l-OI.-wrdqfNkTJSGjAch0mRh-oNfYEbSa85w0P3h-4")


Код ошибки:

2024-05-12 12:26:32 ERROR discord.ext.commands.bot Ignoring exception in command pay
Traceback (most recent call last):
File "C:\Users\Мирон\AppData\Roaming\Python\Python312\site-packages\discord\ext\commands\core.py", line 235, in wrapped
ret = await coro(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Мирон\Downloads\discordbot-master\discordbot-master\main.py", line 48, in pay
user_balances[author.id] -= amount
~~~~~~~~~~~~~^^^^^^^^^^^
KeyError: 1189988964807999659

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

Traceback (most recent call last):
File "C:\Users\Мирон\AppData\Roaming\Python\Python312\site-packages\discord\ext\commands\bot.py", line 1350, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\Мирон\AppData\Roaming\Python\Python312\site-packages\discord\ext\commands\core.py", line 1029, in invoke
await injected(*ctx.args, **ctx.kwargs) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Мирон\AppData\Roaming\Python\Python312\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: KeyError: 1189988964807999659
2024-05-12 12:26:49 ERROR discord.ext.commands.bot Ignoring exception in command casino
Traceback (most recent call last):
File "C:\Users\Мирон\AppData\Roaming\Python\Python312\site-packages\discord\ext\commands\core.py", line 235, in wrapped
ret = await coro(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Мирон\Downloads\discordbot-master\discordbot-master\main.py", line 60, in casino
user_balances[user.id] += result * amount
~~~~~~~~~~~~~^^^^^^^^^
KeyError: 1189988964807999659

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

Traceback (most recent call last):
File "C:\Users\Мирон\AppData\Roaming\Python\Python312\site-packages\discord\ext\commands\bot.py", line 1350, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\Мирон\AppData\Roaming\Python\Python312\site-packages\discord\ext\commands\core.py", line 1029, in invoke
await injected(*ctx.args, **ctx.kwargs) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Мирон\AppData\Roaming\Python\Python312\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: KeyError: 1189988964807999659

Почините пожалуйста!

Нужно установить библиотеки для работы:

discord.py
  • Вопрос задан
  • 72 просмотра
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
if user_balances.get(author.id, initial_balance) < amount:
    await ctx.send('Insufficient funds.')
else:
    user_balances[author.id] -= amount

Ты не рассматриваешь ситуацию, когда пользователь не имеет сохранённого баланса (для него нет записи в user_balances), и но при этом amount <= initial_balance.
В этом случае :
1. get() вернёт initial_balance, так как записи о пользователе нет
2. условие в if не выполнится, так как initial_balance >= amount
3. управление перейдёт в else
4. обращение user_balances[author.id] провалится, так как записи о пользователе нет.

Рекомендую ознакомиться с методом словаря setdefault(), который добавляет ключ в словарь, если его там не было.
Но я бы не заморачивался, а использовать вместо простого словаря класс collections.defaultdict. Он при попытке прочитать несуществующий ключ добавляет его, вызывая указанную функцию для получения значения.
Например:
from collections import defaultdict

balance = defaultdict(lambda: 100)  # по умолчанию значение 100
print(balance)  # выведет defaultdict(..., {}) - в словаре пока ничего нет
print(balance["Вася"])  # выведет 100 - ключ "Вася" добавится автоматически
print(balance)  # выведет defaultdict(..., {'Вася': 100}) - ключ сохранился в словаре
balance['Петя'] += 50  # создаст ключ "Петя" со значением 100, потом добавит к нему 50
print(balance)  # выведет defaultdict(..., {'Вася': 100, 'Петя': 150})

Для своего бота код приспособь сам. Я не знаю, как ты сохраняешь/загружаешь баналс пользователей между запусками бота, но тебе может потребоваться сделать из defaultdict обычный словарь при сохранении, и наоборот - при загрузке.
Вообще я бы не советовал начинать изучения Питона с ботов - это НЕ простая тема.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы