enesd
enesd

Reputation: 3

Addrole command

I want if bots role is lower than the role I want to give user it should error but I dont know how to make it can you please help me?

@client.command() 
@commands.cooldown(1, 5, BucketType.user)
async def addrole(ctx, user: discord.Member, role: discord.Role): 
    if ctx.author.guild_permissions.administrator:
        abc = ctx.guild.roles
        xx = user.roles

        if role in abc:
            if role not in xx:                     
                 await user.add_roles(role)
                 await ctx.send(f'{user.mention}, {role} is given')
            else:
                 await ctx.send(f'The user already has the role')
        else:
             await ctx.send(f'Couldnt find the role')

    else:
         await ctx.send(f'Not enough permissions')

Upvotes: 0

Views: 193

Answers (3)

provit_026
provit_026

Reputation: 11

Simply use try-except to handle your error

if role in abc:
    if role not in xx:
         try:   
              await user.add_roles(role)
              await ctx.send(f'{user.mention}, {role} is given')
         except:
              await ctx.send("Can't give that role!")
    else:
         await ctx.send(f'The user already has the role')
else:
     await ctx.send(f'Couldnt find the role')

Upvotes: 1

chluebi
chluebi

Reputation: 1829

From the official documentation of member.add_roles we can see that if the bot does not have the permission to add the roles it will raise a discord.Forbidden exception. With this we can do the following:

try:
    await user.add_roles(role)
except discord.Forbidden as e:
    ctx.send('This role has a higher permission than the bot')
    # maybe also log the error here

If you are wondering what this try and except business is, here is a quick tutorial.

Note: This is very similar to the solution of @provit_026, but the problem with their solution is that they don't specify the error type, meaning that they will also send the error message if any other error message occurs. So if for example the role requested has not been found by discord.py, it will also send the same error message.

Using try, except without a specific error type is referred to swallowing the error and extremly bad form, as you are potentially having no error messages for any sort of error in everything in the try, except clause.

Upvotes: 1

Diggy.
Diggy.

Reputation: 6944

By default if a bot attempts to give a role to a user that's above its highest role, it throws a Forbidden error.

If you want to catch this error, you can create an error handler for the command, or check the role's hierarchy position:

import traceback # for viewing the full error

@client.command()
@commands.cooldown(...)
async def addrole(...):
    # code
@addrole.error
async def role_err(ctx, error):
    if isinstance(error, commands.errors.CommandInvokeError):
        if isinstance(error.original, discord.Forbidden):
            await ctx.send("I couldn't do that, sorry.")
    traceback.print_exc() # for catching other errors that will happen

Or if you want to check the role's position before adding it (to avoid errors):

@client.command()
@commands.cooldown(...)
async def addrole(ctx, user: discord.Member, role: discord.Role):
    botmember = await ctx.guild.fetch_member(client.user.id)
    if role.position > botmember.top_role.position:
        await ctx.send("Sorry, I can't do that.")
    else:
        await user.add_roles(role)
        await ctx.send("Done!")

References:

Upvotes: 1

Related Questions