mirror of
				https://gitlab.com/ddorn/tfjm-discord-bot.git
				synced 2025-10-29 23:39:52 +01:00 
			
		
		
		
	:recycle:✨ better error handling
This commit is contained in:
		| @@ -49,6 +49,13 @@ class TfjmError(Exception): | |||||||
|         return self.msg |         return self.msg | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class UnwantedCommand(TfjmError): | ||||||
|  |     def __init__(self, msg=None): | ||||||
|  |         if msg is None: | ||||||
|  |             msg = "Cette commande n'était pas attendu à ce moment." | ||||||
|  |         super(UnwantedCommand, self).__init__(msg) | ||||||
|  |  | ||||||
|  |  | ||||||
| class Team: | class Team: | ||||||
|     def __init__(self, ctx, name): |     def __init__(self, ctx, name): | ||||||
|         self.name = name |         self.name = name | ||||||
| @@ -84,16 +91,21 @@ class Tirage: | |||||||
|             "merci de ne pas intervenir." |             "merci de ne pas intervenir." | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     async def dice(self, ctx, author, dice): |     async def dice(self, ctx, n) -> bool: | ||||||
|         await self.phase.dice(ctx, author, dice) |         if n != 100: | ||||||
|  |             raise UnwantedCommand( | ||||||
|  |                 "C'est un dé à 100 faces qu'il faut tirer! (`!dice 100`)" | ||||||
|  |             ) | ||||||
|  |  | ||||||
|  |         await self.phase.dice(ctx, ctx.author, random.randint(1, n)) | ||||||
|         await self.update_phase(ctx) |         await self.update_phase(ctx) | ||||||
|  |  | ||||||
|     async def choose_problem(self, ctx, author, problem): |     async def choose_problem(self, ctx): | ||||||
|         await self.phase.choose_problem(ctx, author, problem) |         await self.phase.choose_problem(ctx, ctx.author, random.choice(PROBLEMS)) | ||||||
|         await self.update_phase(ctx) |         await self.update_phase(ctx) | ||||||
|  |  | ||||||
|     async def accept(self, ctx, author, yes): |     async def accept(self, ctx, yes): | ||||||
|         await self.phase.accept(ctx, author, yes) |         await self.phase.accept(ctx, ctx.author, yes) | ||||||
|         await self.update_phase(ctx) |         await self.update_phase(ctx) | ||||||
|  |  | ||||||
|     async def update_phase(self, ctx): |     async def update_phase(self, ctx): | ||||||
| @@ -118,7 +130,7 @@ class Tirage: | |||||||
|         del tirages[self.channel] |         del tirages[self.channel] | ||||||
|  |  | ||||||
|         # Allow everyone to send messages again |         # Allow everyone to send messages again | ||||||
|         send = discord.PermissionOverwrite(send_messages=None)  # reset |         send = discord.PermissionOverwrite()  # reset | ||||||
|         await ctx.channel.edit(overwrites={ctx.guild.default_role: send}) |         await ctx.channel.edit(overwrites={ctx.guild.default_role: send}) | ||||||
|  |  | ||||||
|     async def show_tirage(self, ctx): |     async def show_tirage(self, ctx): | ||||||
| @@ -185,11 +197,6 @@ class Phase: | |||||||
|         self.round = round |         self.round = round | ||||||
|         self.tirage: Tirage = tirage |         self.tirage: Tirage = tirage | ||||||
|  |  | ||||||
|     async def fais_pas_chier(self, ctx): |  | ||||||
|         await ctx.send( |  | ||||||
|             "Merci d'envoyer seulement les commandes nécessaires et suffisantes." |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def team_for(self, author): |     def team_for(self, author): | ||||||
|         return self.tirage.team_for(author) |         return self.tirage.team_for(author) | ||||||
|  |  | ||||||
| @@ -205,13 +212,13 @@ class Phase: | |||||||
|         return get(ctx.guild.roles, name=CAPTAIN_ROLE).mention |         return get(ctx.guild.roles, name=CAPTAIN_ROLE).mention | ||||||
|  |  | ||||||
|     async def dice(self, ctx: Context, author, dice): |     async def dice(self, ctx: Context, author, dice): | ||||||
|         await self.fais_pas_chier(ctx) |         raise UnwantedCommand() | ||||||
|  |  | ||||||
|     async def choose_problem(self, ctx: Context, author, problem): |     async def choose_problem(self, ctx: Context, author, problem): | ||||||
|         await self.fais_pas_chier(ctx) |         raise UnwantedCommand() | ||||||
|  |  | ||||||
|     async def accept(self, ctx: Context, author, yes): |     async def accept(self, ctx: Context, author, yes): | ||||||
|         await self.fais_pas_chier(ctx) |         raise UnwantedCommand() | ||||||
|  |  | ||||||
|     def finished(self) -> bool: |     def finished(self) -> bool: | ||||||
|         return NotImplemented |         return NotImplemented | ||||||
| @@ -241,9 +248,9 @@ class OrderPhase(Phase): | |||||||
|  |  | ||||||
|         if self.order_for(team) is None: |         if self.order_for(team) is None: | ||||||
|             self.set_order_for(team, dice) |             self.set_order_for(team, dice) | ||||||
|             print(f"Team {team.name} has rolled {dice}") |             await ctx.send(f"L'équipe {team.mention} a obtenu... **{dice}**") | ||||||
|         else: |         else: | ||||||
|             await ctx.send(f"{author.mention}: merci de ne lancer qu'un dé.") |             raise UnwantedCommand("tu as déjà lancé un dé !") | ||||||
|  |  | ||||||
|     def finished(self) -> bool: |     def finished(self) -> bool: | ||||||
|         return all(self.order_for(team) is not None for team in self.teams) |         return all(self.order_for(team) is not None for team in self.teams) | ||||||
| @@ -254,7 +261,7 @@ class OrderPhase(Phase): | |||||||
|             # All dice are different: good |             # All dice are different: good | ||||||
|             self.teams.sort(key=self.order_for, reverse=self.reverse) |             self.teams.sort(key=self.order_for, reverse=self.reverse) | ||||||
|             await ctx.send( |             await ctx.send( | ||||||
|                 f"L'ordre {self.name} pour ce 9 est donc :\n" |                 f"L'ordre {self.name} pour ce tour est donc :\n" | ||||||
|                 " - " |                 " - " | ||||||
|                 + "\n - ".join( |                 + "\n - ".join( | ||||||
|                     f"{team.role.mention} ({self.order_for(team)})" |                     f"{team.role.mention} ({self.order_for(team)})" | ||||||
| @@ -308,22 +315,23 @@ class TiragePhase(Phase): | |||||||
|     async def choose_problem(self, ctx: Context, author, problem): |     async def choose_problem(self, ctx: Context, author, problem): | ||||||
|         team = self.current_team |         team = self.current_team | ||||||
|         if self.team_for(author) != team: |         if self.team_for(author) != team: | ||||||
|             await ctx.send( |             raise UnwantedCommand( | ||||||
|                 f"{author.mention}: c'est à {team.mention} " |                 f"C'est à {team.mention} de choisir " | ||||||
|                 f"de choisir un problème, merci d'attendre :)" |                 f"un problème, merci d'attendre :)" | ||||||
|             ) |             ) | ||||||
|             return |  | ||||||
|  |  | ||||||
|         assert ( |         assert ( | ||||||
|             team.accepted_problems[self.round] is None |             team.accepted_problems[self.round] is None | ||||||
|         ), "Choosing pb for a team that has a pb..." |         ), "Choosing pb for a team that has a pb..." | ||||||
|  |  | ||||||
|         if team.drawn_problem: |         if team.drawn_problem: | ||||||
|             await ctx.send( |             raise UnwantedCommand( | ||||||
|                 "Vous avez déjà tiré un problème, merci de l'accepter (`!yes`) " |                 "Vous avez déjà tiré un problème, merci de l'accepter (`!yes`) " | ||||||
|                 "ou de le refuser (`!no)`." |                 "ou de le refuser (`!no)`." | ||||||
|             ) |             ) | ||||||
|         elif not self.available(problem): |  | ||||||
|  |         await ctx.send(f"{team.mention} a tiré **{problem}** !") | ||||||
|  |         if not self.available(problem): | ||||||
|             await ctx.send( |             await ctx.send( | ||||||
|                 f"Malheureusement, **{problem}** à déjà été choisi, " |                 f"Malheureusement, **{problem}** à déjà été choisi, " | ||||||
|                 f"vous pouvez tirer un nouveau problème." |                 f"vous pouvez tirer un nouveau problème." | ||||||
| @@ -362,11 +370,10 @@ class TiragePhase(Phase): | |||||||
|         team = self.current_team |         team = self.current_team | ||||||
|  |  | ||||||
|         if self.team_for(author) != team: |         if self.team_for(author) != team: | ||||||
|             await ctx.send( |             raise UnwantedCommand( | ||||||
|                 f"{author.mention}: c'est à {team.mention} " |                 f"c'est à {team.mention} " | ||||||
|                 f"de choisir un problème, merci d'attendre :)" |                 f"de choisir un problème, merci d'attendre :)" | ||||||
|             ) |             ) | ||||||
|             return |  | ||||||
|  |  | ||||||
|         assert ( |         assert ( | ||||||
|             team.accepted_problems[self.round] is None |             team.accepted_problems[self.round] is None | ||||||
| @@ -374,14 +381,14 @@ class TiragePhase(Phase): | |||||||
|  |  | ||||||
|         if not team.drawn_problem: |         if not team.drawn_problem: | ||||||
|             if yes: |             if yes: | ||||||
|                 await ctx.send( |                 raise UnwantedCommand( | ||||||
|                     "Vous êtes bien optimistes pour vouloir accepter un problème " |                     "Tu es bien optimiste pour vouloir accepter un problème " | ||||||
|                     "avant de l'avoir tiré !" |                     "avant de l'avoir tiré !" | ||||||
|                 ) |                 ) | ||||||
|             else: |             else: | ||||||
|                 await ctx.send( |                 raise UnwantedCommand( | ||||||
|                     "Halte là ! Ce serait bien de tirer un problème d'abord... " |                     "Halte là ! Ce serait bien de tirer un problème d'abord... " | ||||||
|                     "et peut-être qu'il vous plaira :) " |                     "et peut-être qu'il te plaira :) " | ||||||
|                 ) |                 ) | ||||||
|         else: |         else: | ||||||
|             if yes: |             if yes: | ||||||
| @@ -392,14 +399,13 @@ class TiragePhase(Phase): | |||||||
|                     f"ne peuvent plus l'accepter." |                     f"ne peuvent plus l'accepter." | ||||||
|                 ) |                 ) | ||||||
|             else: |             else: | ||||||
|  |                 msg = f"{team.mention} a refusé **{team.drawn_problem}** " | ||||||
|                 if team.drawn_problem in team.rejected[self.round]: |                 if team.drawn_problem in team.rejected[self.round]: | ||||||
|                     await ctx.send( |                     msg += "sans pénalité." | ||||||
|                         f"{team.mention} a refusé **{team.drawn_problem}** " |  | ||||||
|                         f"sans pénalité." |  | ||||||
|                     ) |  | ||||||
|                 else: |                 else: | ||||||
|  |                     msg += "!" | ||||||
|                     team.rejected[self.round].add(team.drawn_problem) |                     team.rejected[self.round].add(team.drawn_problem) | ||||||
|                     await ctx.send(f"{team.mention} a refusé **{team.drawn_problem}**!") |                 await ctx.send(msg) | ||||||
|  |  | ||||||
|             team.drawn_problem = None |             team.drawn_problem = None | ||||||
|  |  | ||||||
| @@ -542,7 +548,7 @@ async def start_draw(ctx: Context, *teams): | |||||||
|     if len(teams) not in (3, 4): |     if len(teams) not in (3, 4): | ||||||
|         raise TfjmError("Il faut 3 ou 4 équipes pour un tirage.") |         raise TfjmError("Il faut 3 ou 4 équipes pour un tirage.") | ||||||
|  |  | ||||||
|     roles = [role.name for role in ctx.guild.roles] |     roles = {role.name for role in ctx.guild.roles} | ||||||
|     for team in teams: |     for team in teams: | ||||||
|         if team not in roles: |         if team not in roles: | ||||||
|             raise TfjmError("Le nom de l'équipe doit être exactement celui du rôle.") |             raise TfjmError("Le nom de l'équipe doit être exactement celui du rôle.") | ||||||
| @@ -563,6 +569,9 @@ async def start_draw(ctx: Context, *teams): | |||||||
|     await ctx.send( |     await ctx.send( | ||||||
|         "Nous allons commencer le tirage du premier tour. " |         "Nous allons commencer le tirage du premier tour. " | ||||||
|         "Seuls les capitaines de chaque équipe peuvent désormais écrire ici. " |         "Seuls les capitaines de chaque équipe peuvent désormais écrire ici. " | ||||||
|  |         "Merci de d'envoyer seulement ce que est nécessaire et suffusant au " | ||||||
|  |         "bon déroulement du tournoi. Vous pouvez à tout moment poser toute question " | ||||||
|  |         "si quelque chose n'est pas clair ou ne va pas. \n\n" | ||||||
|         "Pour plus de détails sur le déroulement du tirgae au sort, le règlement " |         "Pour plus de détails sur le déroulement du tirgae au sort, le règlement " | ||||||
|         "est accessible sur https://tfjm.org/reglement." |         "est accessible sur https://tfjm.org/reglement." | ||||||
|     ) |     ) | ||||||
| @@ -609,19 +618,15 @@ async def on_ready(): | |||||||
|     usage="n", |     usage="n", | ||||||
| ) | ) | ||||||
| async def dice(ctx: Context, n: int): | async def dice(ctx: Context, n: int): | ||||||
|     if n < 1: |  | ||||||
|         raise TfjmError(f"Je ne peux pas lancer un dé à {n} faces, désolé.") |  | ||||||
|  |  | ||||||
|     dice = random.randint(1, n) |  | ||||||
|     await ctx.send(f"Le dé à {n} faces s'est arrêté sur... **{dice}**") |  | ||||||
|  |  | ||||||
|     # Here we seed the result to Tirage if needed |  | ||||||
|     channel = ctx.channel.id |     channel = ctx.channel.id | ||||||
|     if n == 100 and channel in tirages: |     if channel in tirages: | ||||||
|         # If it is a captain |         await tirages[channel].dice(ctx, n) | ||||||
|         author: discord.Member = ctx.author |     else: | ||||||
|         if get(author.roles, name=CAPTAIN_ROLE) is not None: |         if n < 1: | ||||||
|             await tirages[channel].dice(ctx, author, dice) |             raise TfjmError(f"Je ne peux pas lancer un dé à {n} faces, désolé.") | ||||||
|  |  | ||||||
|  |         dice = random.randint(1, n) | ||||||
|  |         await ctx.send(f"Le dé à {n} face{'s'*(n>1)} s'est arrêté sur... **{dice}**") | ||||||
|  |  | ||||||
|  |  | ||||||
| @bot.command( | @bot.command( | ||||||
| @@ -641,17 +646,12 @@ async def choose(ctx: Context, *args): | |||||||
|     aliases=["rp", "problème-aléatoire", "probleme-aleatoire", "pa"], |     aliases=["rp", "problème-aléatoire", "probleme-aleatoire", "pa"], | ||||||
| ) | ) | ||||||
| async def random_problem(ctx: Context): | async def random_problem(ctx: Context): | ||||||
|     problems = open("problems").readlines() |  | ||||||
|     problems = [p.strip() for p in problems] |  | ||||||
|     problem = random.choice(problems) |  | ||||||
|     await ctx.send(f"Le problème tiré est... **{problem}**") |  | ||||||
|  |  | ||||||
|     channel = ctx.channel.id |     channel = ctx.channel.id | ||||||
|     if channel in tirages: |     if channel in tirages: | ||||||
|         # If it is a captain |         await tirages[channel].choose_problem(ctx) | ||||||
|         author: discord.Member = ctx.author |     else: | ||||||
|         if get(author.roles, name=CAPTAIN_ROLE) is not None: |         problem = random.choice(PROBLEMS) | ||||||
|             await tirages[channel].choose_problem(ctx, ctx.author, problem) |         await ctx.send(f"Le problème tiré est... **{problem}**") | ||||||
|  |  | ||||||
|  |  | ||||||
| @bot.command( | @bot.command( | ||||||
| @@ -662,31 +662,41 @@ async def random_problem(ctx: Context): | |||||||
| async def accept_cmd(ctx): | async def accept_cmd(ctx): | ||||||
|     channel = ctx.channel.id |     channel = ctx.channel.id | ||||||
|     if channel in tirages: |     if channel in tirages: | ||||||
|         # If it is a captain |         await tirages[channel].accept(ctx, True) | ||||||
|         author: discord.Member = ctx.author |     else: | ||||||
|         if get(author.roles, name=CAPTAIN_ROLE) is not None: |         await ctx.send(f"{ctx.author.mention} approuve avec vigeur !") | ||||||
|             await tirages[channel].accept(ctx, ctx.author, True) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @bot.command( | @bot.command( | ||||||
|     name="refuse", |     name="refuse", | ||||||
|     help="Refuse le problème qui vient d'être tiré. \n Ne fonctionne que lors d'un tirage.", |     help="Refuse le problème qui vient d'être tiré. \n Ne fonctionne que lors d'un tirage.", | ||||||
|     aliases=["non", "no", "n"], |     aliases=["non", "no", "n", "nope", "jaaamais"], | ||||||
| ) | ) | ||||||
| async def refuse_cmd(ctx): | async def refuse_cmd(ctx): | ||||||
|     channel = ctx.channel.id |     channel = ctx.channel.id | ||||||
|     if channel in tirages: |     if channel in tirages: | ||||||
|         # If it is a captain |         await tirages[channel].accept(ctx, False) | ||||||
|         author: discord.Member = ctx.author |     else: | ||||||
|         if get(author.roles, name=CAPTAIN_ROLE) is not None: |         await ctx.send(f"{ctx.author.mention} nie tout en block !") | ||||||
|             await tirages[channel].accept(ctx, ctx.author, False) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @bot.event | @bot.event | ||||||
| async def on_command_error(ctx: Context, error, *args, **kwargs): | async def on_command_error(ctx: Context, error, *args, **kwargs): | ||||||
|     if isinstance(error, commands.CommandInvokeError): |     if isinstance(error, commands.CommandInvokeError): | ||||||
|         msg = str(error.original) or str(error) |         if isinstance(error.original, UnwantedCommand): | ||||||
|         traceback.print_tb(error.original.__traceback__, file=sys.stderr) |             await ctx.message.delete() | ||||||
|  |             author: discord.Message | ||||||
|  |             await ctx.author.send( | ||||||
|  |                 "J'ai supprimé ton message:\n> " | ||||||
|  |                 + ctx.message.clean_content | ||||||
|  |                 + "\n\nC'est pas grave, c'est juste pour ne pas encombrer " | ||||||
|  |                 "le chat lors du tirage." | ||||||
|  |             ) | ||||||
|  |             await ctx.author.send("Raison: " + error.original.msg) | ||||||
|  |             return | ||||||
|  |         else: | ||||||
|  |             msg = str(error.original) or str(error) | ||||||
|  |             traceback.print_tb(error.original.__traceback__, file=sys.stderr) | ||||||
|     else: |     else: | ||||||
|         msg = str(error) |         msg = str(error) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user