♻️✨ better error handling
This commit is contained in:
parent
4c63c0509e
commit
ab1e772d7d
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue