mirror of
https://gitlab.com/ddorn/tfjm-discord-bot.git
synced 2025-05-18 07:32:47 +00:00
104 lines
2.9 KiB
Python
104 lines
2.9 KiB
Python
import sys
|
|
import traceback
|
|
|
|
import discord
|
|
from discord.ext.commands import *
|
|
from discord.utils import maybe_coroutine
|
|
|
|
from src.core import CustomBot
|
|
from src.errors import UnwantedCommand, TfjmError
|
|
|
|
# Global variable and function because I'm too lazy to make a metaclass
|
|
handlers = {}
|
|
|
|
|
|
def handles(error_type):
|
|
"""
|
|
This registers an error handler.
|
|
|
|
Error handlers can be coroutines or functions.
|
|
"""
|
|
|
|
def decorator(f):
|
|
handlers[error_type] = f
|
|
return f
|
|
|
|
return decorator
|
|
|
|
|
|
class ErrorsCog(Cog):
|
|
"""This cog defines all the handles for errors."""
|
|
|
|
def __init__(self, bot: CustomBot):
|
|
self.bot = bot
|
|
|
|
@Cog.listener()
|
|
async def on_command_error(self, ctx: Context, error: CommandError):
|
|
print(repr(error), file=sys.stderr)
|
|
|
|
# We take the first superclass with an handler defined
|
|
handler = None
|
|
for type_ in error.__class__.__mro__:
|
|
handler = handlers.get(type_)
|
|
if handler:
|
|
break
|
|
|
|
if handler is None:
|
|
# Default handling
|
|
msg = repr(error)
|
|
else:
|
|
msg = await maybe_coroutine(handler, self, ctx, error)
|
|
|
|
if msg:
|
|
message = await ctx.send(msg)
|
|
await self.bot.wait_for_bin(ctx.message.author, message)
|
|
|
|
@handles(UnwantedCommand)
|
|
async def on_unwanted_command(self, ctx, error: UnwantedCommand):
|
|
await ctx.message.delete()
|
|
author: discord.Message
|
|
await ctx.author.send(
|
|
"J'ai supprimé ton message:\n> "
|
|
+ ctx.message.clean_content
|
|
+ "\nC'est pas grave, c'est juste pour ne pas encombrer "
|
|
"le chat lors du tirage."
|
|
)
|
|
await ctx.author.send("Raison: " + error.msg)
|
|
|
|
@handles(TfjmError)
|
|
async def on_tfjm_error(self, ctx: Context, error: TfjmError):
|
|
msg = await ctx.send(error.msg)
|
|
await self.bot.wait_for_bin(ctx.author, msg)
|
|
|
|
@handles(CommandInvokeError)
|
|
async def on_command_invoke_error(self, ctx, error):
|
|
specific_handler = handlers.get(type(error.original))
|
|
|
|
if specific_handler:
|
|
return await specific_handler(self, ctx, error.original)
|
|
|
|
traceback.print_tb(error.original.__traceback__, file=sys.stderr)
|
|
return (
|
|
error.original.__class__.__name__
|
|
+ ": "
|
|
+ (str(error.original) or str(error))
|
|
)
|
|
|
|
@handles(CommandNotFound)
|
|
def on_command_not_found(self, ctx, error):
|
|
|
|
# Here we just take advantage that the error is formatted this way:
|
|
# 'Command "NAME" is not found'
|
|
name = str(error).partition('"')[2].rpartition('"')[0]
|
|
return f"La commande {name} n'existe pas. Pour une liste des commandes, envoie `!help`."
|
|
|
|
@handles(MissingRole)
|
|
def on_missing_role(self, ctx, error):
|
|
return (
|
|
f"Il te faut le role de {error.missing_role} pour utiliser cette commande."
|
|
)
|
|
|
|
|
|
def setup(bot):
|
|
bot.add_cog(ErrorsCog(bot))
|