So I was looking at this question and I cant get the code to work, i would have pushed a comment on the initial question post but i dont have enough rep
I apologize if this seems like i dont know what im doing its prolly bc i dont, i never worked with warns before.
and the errors that i get when ever i use the warn command is:
Ignoring exception in command warn:
Traceback (most recent call last):
File "/home/runner/dnunus-5/venv/lib/python3.8/site-packages/discord/ext/commands/core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "main.py", line 123, in warn
save_warn(ctx, member)
File "main.py", line 99, in save_warn
warns[str(member.id)] = 1
KeyError: '472100676407656448'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/runner/dnunus-5/venv/lib/python3.8/site-packages/discord/ext/commands/bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "/home/runner/dnunus-5/venv/lib/python3.8/site-packages/discord/ext/commands/core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "/home/runner/dnunus-5/venv/lib/python3.8/site-packages/discord/ext/commands/core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: KeyError: '472100676407656448'
def save_warn(ctx, member: discord.Member):
with open('warns.json', 'r') as f:
warns = json.load(f)
warns[str(member.id)] = 1
with open('warns.json', 'w') as f:
json.dump(warns, f)
def remove_warn(ctx, member: discord.Member, amount: int):
with open('warns.json', 'r') as f:
warns = json.load(f)
warns[str(member.id)] -= amount
with open('warns.json', 'w') as f:
json.dump(warns, f)
def warns_check(member: discord.Member):
with open('warns.json', 'r') as f:
warns = json.load(f)
warns[str(member.id)]
return warns
@bot.command()
@commands.has_permissions(kick_members=True)
async def warn(ctx, member: discord.Member, *, reason):
save_warn(ctx, member)
dm = await bot.fetch_user(member.id)
em=discord.Embed(title="Warning", description=f"Server: {ctx.guild.id}\nReason: {reason}")
await dm.send(embed=em)
@bot.command()
@commands.has_permissions(kick_members=True)
async def warnings(ctx, member: discord.Member):
warns = warns_check(member)
await ctx.send(f"{member.name} has {warns} warnings.")
@bot.command()
@commands.has_permissions(kick_members=True)
async def rmwarn(ctx, member: discord.Member, amount: int):
remove_warn(ctx, member, amount)
await ctx.send(f"Removed {amount} warnings from {member.name}!")
CodePudding user response:
You need to make sure the key exists before you try to access it.
One way to do it is to set the warning count to 0 if the member isn't already known.
The warns_check
of that code is also broken.
def save_warn(ctx, member: discord.Member):
with open('warns.json', 'r') as f:
warns = json.load(f)
# if `str(member.id)` isn't in `warns`, then return 0
warns[str(member.id)] = warns.get(str(member.id), 0) 1
with open('warns.json', 'w') as f:
json.dump(warns, f)
def remove_warn(ctx, member: discord.Member, amount: int):
with open('warns.json', 'r') as f:
warns = json.load(f)
warns[str(member.id)] = warns.get(str(member.id), 0) - amount
with open('warns.json', 'w') as f:
json.dump(warns, f)
def warns_check(member: discord.Member):
with open('warns.json', 'r') as f:
warns = json.load(f)
return warns.get(str(member.id), 0)
Note that it's not the best practice to open and close the files every time you need to read the input. You would be better off loading the input once, and then saving it periodically like this:
@tasks.loop(minutes=1.0)
async def autosave():
with open(...) as f:
json.dump(warns, f)
autosave()
with open(...) as f:
warns = json.load(f)