Files
mustafa/src/cogs/errors.py
T
2022-11-17 22:03:23 +01:00

182 lines
6.8 KiB
Python

import traceback
import discord
from discord import app_commands
from discord.ext import commands
from cogs.utils import embed_templates
from cogs.utils.misc_utils import ignore_exception
class Errors(commands.Cog):
"""Error handlers for commands"""
def __init__(self, bot: commands.Bot):
"""
Parameters
----------
bot (commands.Bot): The bot instance
"""
self.bot = bot
bot.tree.on_error = self.on_app_command_error # Set error handler for slash commands
@commands.Cog.listener()
async def on_command(self, ctx: commands.Context):
"""
Logs prefix command execution metadata
Parameters
----------
ctx (commands.Context): Context object
"""
self.bot.logger.info(
f'{"❌ " if ctx.command_failed else "✔ "} {ctx.command} | ' +
f'{ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id}) | ' +
f'{ctx.guild.id}-{ctx.channel.id}-{ctx.message.id}'
)
@commands.Cog.listener()
async def on_app_command_completion(self, interaction: discord.Interaction, command: app_commands.Command | app_commands.ContextMenu):
"""
Logs slash command execution metadata
Parameters
----------
interaction (discord.Interaction): Slash command context object
command (app_commands.Command | app_commands.ContextMenu): Command object
"""
self.bot.logger.info(
f'{"❌ " if interaction.command_failed else "✔ "} {command.name} | ' +
f'{interaction.user.name}#{interaction.user.discriminator} ({interaction.user.id}) | ' +
f'{interaction.guild_id}-{interaction.channel_id}-{interaction.id}'
)
@commands.Cog.listener()
async def on_command_error(self, ctx: commands.Context, error: commands.CommandError):
"""
Handle prefix command errors
Parameters
----------
ctx (commands.Context): Context object
error (commands.CommandError): Eror context object
"""
# Reset cooldown if command throws AttributeError
with ignore_exception(AttributeError):
self.bot.get_command(f'{ctx.command}').reset_cooldown(ctx)
# Ignore command's own error handling
if hasattr(ctx.command, 'on_error'):
return
# Ignored errors
ignored = commands.CommandNotFound
error = getattr(error, 'original', error)
if isinstance(error, ignored):
return
send_help = (
commands.MissingRequiredArgument,
commands.TooManyArguments,
commands.BadArgument
)
if isinstance(error, send_help):
self.bot.get_command(f'{ctx.command}').reset_cooldown(ctx)
return await ctx.send_help(ctx.command)
elif isinstance(error, commands.BotMissingPermissions):
permissions = ', '.join(error.missing_perms)
text = 'Jeg mangler følgende tillatelser:\n\n' + \
f'```\n{permissions}\n```'
return await ctx.send(text)
elif isinstance(error, commands.MissingPermissions):
permissions = ', '.join(error.missing_perms)
text = 'Du mangler følgende tillatelser\n\n' + \
f'```\n{permissions}\n```'
return await ctx.send(text)
elif isinstance(error, commands.NotOwner):
text = 'Bare boteieren kan gjøre dette'
return await ctx.send(text)
elif isinstance(error, commands.CommandOnCooldown):
text = 'Kommandoen har nettopp blitt brukt' + \
f'Prøv igjen om `{error.retry_after:.1f}` sekunder.'
return await ctx.send(text)
elif isinstance(error, commands.NoPrivateMessage):
try:
text = 'Denne kommandoen kan bare utføres i servere'
return await ctx.send(text)
except discord.errors.Forbidden: # Thrown if bot is blocked by the user or if the user has closed their DMs
print('DM Blocked!')
elif isinstance(error, commands.DisabledCommand):
pass
elif isinstance(error, commands.CheckFailure):
return
embed = embed_templates.error_fatal(ctx, text='En ukjent feil oppstod!')
await ctx.send(embed=embed)
# Log full exception to file
self.bot.logger.error(''.join(traceback.format_exception(type(error), error, error.__traceback__)))
async def on_app_command_error(self, interaction: discord.Interaction, error: app_commands.AppCommandError):
"""
Handle slash command errors
Parameters
----------
interaction (discord.Interaction): Slash command context object
error (app_commands.AppCommandError): Eror context object
"""
# Log command usage, just in case
await self.on_app_command_completion(interaction, interaction.command)
if isinstance(error, commands.BotMissingPermissions):
permissions = ', '.join(error.missing_perms)
embed = embed_templates.error_warning(interaction, text='Jeg mangler følgende tillatelser:\n\n' +
f'```\n{permissions}\n```')
return await interaction.response.send_message(embed=embed)
elif isinstance(error, commands.MissingPermissions):
permissions = ', '.join(error.missing_perms)
embed = embed_templates.error_warning(interaction, text='Du mangler følgende tillatelser\n\n' +
f'```\n{permissions}\n```')
return await interaction.response.send_message(embed=embed)
elif isinstance(error, commands.NotOwner):
embed = embed_templates.error_fatal(interaction, text='Bare boteieren kan gjøre dette')
return await interaction.response.send_message(embed=embed)
elif isinstance(error, commands.CommandOnCooldown):
embed = embed_templates.error_warning(interaction, text='Kommandoen har nettopp blitt brukt' +
f'Prøv igjen om `{error.retry_after:.1f}` sekunder.')
return await interaction.response.send_message(embed=embed)
embed = embed_templates.error_fatal(interaction, text='En ukjent feil oppstod!')
await interaction.response.send_message(embed=embed)
# Log full exception to file
self.bot.logger.error(''.join(traceback.format_exception(type(error), error, error.__traceback__)))
async def setup(bot: commands.Bot):
"""
Add the cog to the bot on extension load
Parameters
----------
bot (commands.Bot): Bot instance
"""
await bot.add_cog(Errors(bot))