async def on_command_error(self, ctx, error): """The event triggered when an error is raised while invoking a command.""" async def send_del(*args, **kwargs): await ctx.reply(*args, delete_after=60, mention_author=False, **kwargs) if ctx.me.permissions_in(ctx.channel).manage_messages: with contextlib.suppress(discord.NotFound): await ctx.message.delete(delay=60) if hasattr(ctx.command, 'on_error'): return cog = ctx.cog if cog: if cog._get_overridden_method(cog.cog_command_error) is not None: return ignored = (commands.CommandNotFound, ) default_error = (commands.NotOwner, commands.TooManyArguments, flags.ArgumentParsingError, NotInDpy) error = getattr(error, 'original', error) if isinstance(error, ignored): return if isinstance(error, commands.DisabledCommand): await send_del(f'{ctx.command} has been disabled.') elif isinstance(error, commands.CommandOnCooldown): if ctx.author == self.bot.stella: return await ctx.reinvoke() await send_del(embed=BaseEmbed.to_error( title="Cooldown Error", description= f"You're on cooldown. Retry after `{error.retry_after:.2f}` seconds" )) elif isinstance(error, default_error): await send_del(embed=BaseEmbed.to_error(description=f"{error}")) else: if template := await self.generate_signature_error(ctx, error): await send_del(embed=template) else:
async def generate_signature_error(self, ctx, error): command = ctx.command help_com = self.bot.help_command help_com.context = ctx real_signature = help_com.get_command_signature(command, ctx) if ctx.current_parameter is None: return parameter = [*ctx.command.params.values() ][ctx.command.cog is not None:] pos = parameter.index(ctx.current_parameter) list_sig = real_signature.split() pos += list_sig.index(ctx.invoked_with) target = list_sig[pos] print(target, "here") target_list = list(target) alpha_index = [ i for i, a in enumerate(target) if a.isalnum() or a in ("|", '"') ] minimum, maximum = min(alpha_index), max(alpha_index) target_list[minimum] = target_list[minimum].capitalize() list_sig[pos] = "".join(target_list) space = " " * sum([len(x) + 1 for x in list_sig[:pos]]) offset = " " * int((minimum + 1 + (maximum - minimum)) / 2) embed = BaseEmbed.to_error(description=f"```{error}```\n") embed.description += f"**Errored at**\n" \ f"```prolog\n" \ f"{' '.join(list_sig)}\n" \ f"{space}{offset}^\n" \ f"```\n" if (demo := help_com.get_demo(command)) and isinstance( error, commands.MissingRequiredArgument): cooldown = self.error_cooldown bucket = cooldown.get_bucket(ctx.message) if not bucket.update_rate_limit(): embed.description += "**Command Example**" embed.set_image(url=demo)
elif isinstance(error, commands.CommandOnCooldown): if ctx.author == self.bot.stella: return await ctx.reinvoke() await send_del(embed=BaseEmbed.to_error( title="Cooldown Error", description= f"You're on cooldown. Retry after `{error.retry_after:.2f}` seconds" )) elif isinstance(error, default_error): await send_del(embed=BaseEmbed.to_error(description=f"{error}")) else: if template := await self.generate_signature_error(ctx, error): await send_del(embed=template) else: await send_del(embed=BaseEmbed.to_error(description=f"{error}") ) traceback_error = print_exception( f'Ignoring exception in command {ctx.command}:', error) if not self.bot.tester: error_message = f"**Command:** {ctx.message.content}\n" \ f"**Message ID:** `{ctx.message.id}`\n" \ f"**Author:** `{ctx.author}`\n" \ f"**Guild:** `{ctx.guild}`\n" \ f"**Channel:** `{ctx.channel}`\n" \ f"**Jump:** [`jump`]({ctx.message.jump_url})```py\n" \ f"{traceback_error}\n" \ f"```" await self.bot.error_channel.send( embed=BaseEmbed.default(ctx, description=error_message) )
async def connect4(self, ctx, player2: Player): GAME = "Connect 4" message = BaseEmbed.invite(ctx, GAME, status=None, invitation=self.INVITATION.format( player2, ctx, GAME)) message["content"] = player2.mention responses_text = tuple( BaseEmbed.invite(ctx, GAME, status=not x, invited=player2) for x in range(2)) # first is approve, second disapprove responses = { ctx.bot.INVITE_REACT[1 - x]: y for x, y in zip(range(2), responses_text) } game = self.bot.global_player.add(ctx, [player2.id], game_classes.Connect4) error = f"Looks like {{}} seconds is up! Sorry **{ctx.author}**, You will have to request for another one" respond = await prompt(ctx, message=message, event_type="reaction_add", responses=responses, error=error, target_id={player2.id}) if not respond: self.bot.global_player.remove(game) return game.status = True def check_turn(game): def predicate(m): checking = (m.author in (game.current_player, self.bot.stella), m.content.isdigit() and 1 <= int(m.content) <= game.cols) return all(checking) return predicate async def connect4_prompt(game, message=None): if not message: display = await game.render_board() player = game.current_player description = f"`{player}`, It's your turn. Please choose a column between `1` to `7`." message = BaseEmbed.board(player.mention, game.color, display, "connect_4", title="Connect 4", description=description) error = f"`{{}}` seconds is up. Looks like `{game.last_player}` wins" return await prompt(ctx, message=message, predicate=check_turn(game), error=error, delete_after=True, ret=True, delete_timeout=True) message_sent = None while response := await connect4_prompt(game, message_sent): if isinstance(response, discord.Message): message_sent = None if game_result := await atry_catch(game.insert, int(response.content) - 1, ret=True): if not isinstance(game_result, Connect4ColumnFull): await ctx.send(**game_result) break else: message_sent = { "embed": BaseEmbed.to_error(title="Connect 4", description=str(game_result)) }