Reputation: 3
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
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
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
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:
Client.user
Guild.fetch_member()
Member.top_role
Role.position
- "The bottom role has a position of 0".Member.add_roles()
Command.error
commands.CommandInvokeError
discord.Forbidden
traceback.print_exc()
Upvotes: 1