0

My warn command is supposed to mute a member for an hour after 3 warns, but when it muted the member, the command stops working and the .json file gets cleared. Does anyone know why?


@client.command()
@commands.has_permissions(manage_roles = True)
async def warn(ctx, member : discord.Member, *, reason=None):
    with open("warned_members.json", "r") as f:
        warned_ones = json.load(f)

    try:
        with open("warned_members.json", "r") as f:
           if warned_ones[str(member)] == 1 or 2 or 3:
               pass
    except:
        with open("warned_members.json", "w") as f:
            warned_ones[str(member)] = 1
            json.dump(warned_ones, f, indent=5)
            warn_embed = discord.Embed(title='Member Warned', description=f"{member} has been warned.")
            warn_embed.add_field(name='Reason', value=f"{reason}")
            await ctx.send(embed=warn_embed)
            return
    if warned_ones[str(member)] == 1:
        warned_ones[str(member)] = 2
        with open("warned_members.json", "w") as f:
            json.dump(warned_ones, f, indent=5)
            warn_embed = discord.Embed(title='Member Warned', description=f"{member} has been warned.")
            warn_embed.add_field(name='Reason', value=f"{reason}")
            await ctx.send(embed=warn_embed)
            return
    if warned_ones[str(member)] == 2:
        try:
            muted_role = discord.utils.get(ctx.guild.roles, name="Muted")
            time = 3600
            await member.add_roles(muted_role, reason=None, atomic=True)
            warned_ones.pop(str(member))
            with open("warned_members.json", "w") as f:
                json.dump(warned_ones, f, indent=5)
                warn_embed = discord.Embed(title='Member Muted', description=f"{member} has been muted for 1 hour.")
                warn_embed.add_field(name='Reason', value=f"3 warns reached.")
                await ctx.send(embed=warn_embed)
                await asyncio.sleep(time)
        except:        
            await ctx.send("Muted role not found")
  • In general, rewriting your data file in-place is _always_ a risky proposition. Write new contents to a temporary file, and rename it over the "real"/final file after everything is flushed and valid. – Charles Duffy Mar 14 '21 at 19:40
  • See [How to safely write to a file?](https://stackoverflow.com/questions/1812115/how-to-safely-write-to-a-file), though I recommend [the answer by u0b34a0f6ae](https://stackoverflow.com/a/1812421/14122), not the accepted one. You should really _just_ be creating a temporary file, and renaming it over the "real" file when flushed. – Charles Duffy Mar 14 '21 at 19:40
  • Also, note that `warned_ones[str(member)] == 1 or 2 or 3` is **always** true, because it's read like `(warned_ones[str(member)] == 1) or (2) or (3)`, and both `2` and `3` are true. Thus, just as `False or True` is always true, `some-maybe-true-condition or True` is also always true. – Charles Duffy Mar 14 '21 at 19:44
  • Anyhow -- you should be able to build a [mre] that reproduces your problem without using discord.py or depending on user or network input. Always better (and required, to satisfy the "minimal" part of the above-linked rules) to simplify before asking a question. – Charles Duffy Mar 14 '21 at 19:45
  • (maybe you meant `warned_ones[str(member)] in (1,2,3)`?) – Charles Duffy Mar 14 '21 at 19:51

0 Answers0