From ce0b73597a05bdf20b6d2c1147e9931c903e1c9b Mon Sep 17 00:00:00 2001 From: MattyTheHacker <18513864+MattyTheHacker@users.noreply.github.com> Date: Mon, 27 May 2024 19:23:54 +0100 Subject: [PATCH 1/9] add archive debug logging --- cogs/archive.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cogs/archive.py b/cogs/archive.py index 704be4ea..233e6d5c 100644 --- a/cogs/archive.py +++ b/cogs/archive.py @@ -105,6 +105,7 @@ async def archive(self, ctx: TeXBotApplicationContext, str_category_id: str) -> ctx, message=f"Category with ID {str(category_id)!r} does not exist.", ) + logger.debug("Category with ID: %s could not be found!", str(category_id)) return if "archive" in category.name: @@ -115,6 +116,10 @@ async def archive(self, ctx: TeXBotApplicationContext, str_category_id: str) -> ), ephemeral=True, ) + logger.debug( + "Category %s was already archived when the archive command was run", + category.name, + ) return # noinspection PyUnreachableCode @@ -216,3 +221,4 @@ async def archive(self, ctx: TeXBotApplicationContext, str_category_id: str) -> return await ctx.respond("Category successfully archived", ephemeral=True) + logger.debug("Category %s has been successfully archived.", category.name) From da454e7dfcebb64d15ac9706679e3ba547ce1034 Mon Sep 17 00:00:00 2001 From: MattyTheHacker <18513864+MattyTheHacker@users.noreply.github.com> Date: Mon, 27 May 2024 19:50:25 +0100 Subject: [PATCH 2/9] add more debug logging --- cogs/delete_all.py | 6 ++++++ cogs/edit_message.py | 13 +++++++++++++ cogs/induct.py | 23 +++++++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/cogs/delete_all.py b/cogs/delete_all.py index aafb9ecc..2031fb2a 100644 --- a/cogs/delete_all.py +++ b/cogs/delete_all.py @@ -5,12 +5,17 @@ __all__: Sequence[str] = ("DeleteAllCommandsCog",) +import logging +from logging import Logger + import discord from db.core.models import DiscordReminder, GroupMadeMember from db.core.models.utils import AsyncBaseModel from utils import CommandChecks, TeXBotApplicationContext, TeXBotBaseCog +logger: Logger = logging.getLogger("TeX-Bot") + class DeleteAllCommandsCog(TeXBotBaseCog): """Cog class that defines the "/delete-all" command group and command call-back methods.""" @@ -36,6 +41,7 @@ async def _delete_all(ctx: TeXBotApplicationContext, delete_model: type[AsyncBas f"All {delete_model_instances_name_plural} deleted successfully.", ephemeral=True, ) + logger.debug("All %s have been deleted.", delete_model_instances_name_plural) @delete_all.command( name="reminders", diff --git a/cogs/edit_message.py b/cogs/edit_message.py index fb230b4b..689d6b83 100644 --- a/cogs/edit_message.py +++ b/cogs/edit_message.py @@ -5,7 +5,9 @@ __all__: Sequence[str] = ("EditMessageCommandCog",) +import logging import re +from logging import Logger import discord @@ -18,6 +20,8 @@ TeXBotBaseCog, ) +logger: Logger = logging.getLogger("TeX-Bot") + class EditMessageCommandCog(TeXBotBaseCog): # noinspection SpellCheckingInspection @@ -93,6 +97,7 @@ async def edit_message(self, ctx: TeXBotApplicationContext, str_channel_id: str, ctx, message=f"{str_channel_id!r} is not a valid channel ID.", ) + logger.debug("Channel ID %s was not valid.", str_channel_id) return channel_id: int = int(str_channel_id) @@ -102,6 +107,7 @@ async def edit_message(self, ctx: TeXBotApplicationContext, str_channel_id: str, ctx, message=f"{str_message_id!r} is not a valid message ID.", ) + logger.debug("Message ID %s was not valid.", str_message_id) return message_id: int = int(str_message_id) @@ -115,6 +121,7 @@ async def edit_message(self, ctx: TeXBotApplicationContext, str_channel_id: str, ctx, message=f"Text channel with ID \"{channel_id}\" does not exist.", ) + logger.debug("Channel ID %s is not a text channel.", channel_id) return try: @@ -124,6 +131,7 @@ async def edit_message(self, ctx: TeXBotApplicationContext, str_channel_id: str, ctx, message=f"Message with ID \"{message_id}\" does not exist.", ) + logger.debug("Message ID %s could not be found.", message_id) return try: @@ -136,6 +144,11 @@ async def edit_message(self, ctx: TeXBotApplicationContext, str_channel_id: str, "because it belongs to another user." ), ) + logger.debug( + "Message ID %s does not belong to the bot, so could not be edited.", + message_id, + ) return else: await ctx.respond("Message edited successfully.", ephemeral=True) + logger.debug("Message ID %s has been edited successfully.", message_id) diff --git a/cogs/induct.py b/cogs/induct.py index a8a14e53..7232ee63 100644 --- a/cogs/induct.py +++ b/cogs/induct.py @@ -112,6 +112,7 @@ async def on_member_update(self, before: discord.Member, after: discord.Member) "(You can do this by right-clicking your name in the members-list " "to the right & selecting \"Edit Server Profile\").", ) + logger.debug("Sent welcome message to %s", after) if user_type != "member": await after.send( f"You can also get yourself an annual membership " @@ -123,6 +124,7 @@ async def on_member_update(self, before: discord.Member, after: discord.Member) ":green_square:! " f"Checkout all the perks at {settings["MEMBERSHIP_PERKS_URL"]}", ) + logger.debug("Sent member message to %s", after) except discord.Forbidden: logger.info( "Failed to open DM channel to user %s so no welcome message was sent.", @@ -200,6 +202,10 @@ async def _perform_induction(self, ctx: TeXBotApplicationContext, induction_memb ctx, message="Member cannot be inducted because they are a bot.", ) + logger.debug( + "Member %s could not be inducted because they are a bot.", + induction_member, + ) return if guest_role in induction_member.roles: @@ -209,6 +215,10 @@ async def _perform_induction(self, ctx: TeXBotApplicationContext, induction_memb "User has already been inducted. :information_source:" ), ) + logger.debug( + "User %s was not inducted because they already have the guest role.", + induction_member, + ) return if not silent: @@ -224,6 +234,10 @@ async def _perform_induction(self, ctx: TeXBotApplicationContext, induction_memb async for message in general_channel.history(limit=7): if message.author == self.bot.user and "grab your roles" in message.content: message_already_sent = True + logger.debug( + "Welcome message not sent to %s because it's already been sent!", + induction_member, + ) break if not message_already_sent: @@ -232,11 +246,13 @@ async def _perform_induction(self, ctx: TeXBotApplicationContext, induction_memb f"Remember to grab your roles in {roles_channel_mention} " "and say hello to everyone here! :wave:", ) + logger.debug("General induction message for user %s has been sent.") await induction_member.add_roles( guest_role, reason=f"{ctx.user} used TeX Bot slash-command: \"/induct\"", ) + logger.debug("Added guest role to %s", induction_member) applicant_role: discord.Role | None = discord.utils.get( main_guild.roles, @@ -248,10 +264,12 @@ async def _perform_induction(self, ctx: TeXBotApplicationContext, induction_memb applicant_role, reason=f"{ctx.user} used TeX Bot slash-command: \"/induct\"", ) + logger.debug("Removed Applicant role from %s", induction_member) tex_emoji: discord.Emoji | None = self.bot.get_emoji(743218410409820213) if not tex_emoji: tex_emoji = discord.utils.get(main_guild.emojis, name="TeX") + logger.debug("Could not find the TeX emoji!") if intro_channel: recent_message: discord.Message @@ -274,6 +292,7 @@ async def _perform_induction(self, ctx: TeXBotApplicationContext, induction_memb break await initial_response.edit(content=":white_check_mark: User inducted successfully.") + logger.debug("Induction completed successfully for user %s", induction_member) class InductCommandCog(BaseInductCog): @@ -491,3 +510,7 @@ async def ensure_members_inducted(self, ctx: TeXBotApplicationContext) -> None: ), ephemeral=True, ) + if changes_made: + logger.debug("Successfully inducted members.") + else: + logger.debug("No members have been inducted. ") From c3a047ffa7d9d2fe9f32c3c829442232e109ed82 Mon Sep 17 00:00:00 2001 From: MattyTheHacker <18513864+MattyTheHacker@users.noreply.github.com> Date: Mon, 27 May 2024 21:50:58 +0100 Subject: [PATCH 3/9] even more debug messageS --- cogs/kill.py | 3 +++ cogs/make_member.py | 15 +++++++++++++++ cogs/remind_me.py | 1 + cogs/send_get_roles_reminders.py | 1 + cogs/send_introduction_reminders.py | 2 ++ cogs/strike.py | 22 ++++++++++++++++++++++ cogs/write_roles.py | 6 ++++++ 7 files changed, 50 insertions(+) diff --git a/cogs/kill.py b/cogs/kill.py index 41800577..23730102 100644 --- a/cogs/kill.py +++ b/cogs/kill.py @@ -71,6 +71,7 @@ async def kill(self, ctx: TeXBotApplicationContext) -> None: ), view=ConfirmKillView(), ) + logger.debug("Sent kill confirmation message.") confirmation_message: discord.Message = ( response if isinstance(response, discord.Message) @@ -88,6 +89,8 @@ async def kill(self, ctx: TeXBotApplicationContext) -> None: ), ) + logger.debug("Kill confirmation recieved: %s", button_interaction) + await confirmation_message.edit(view=None) if button_interaction.data["custom_id"] == "shutdown_confirm": # type: ignore[index, typeddict-item] diff --git a/cogs/make_member.py b/cogs/make_member.py index be6c681f..224b5eff 100644 --- a/cogs/make_member.py +++ b/cogs/make_member.py @@ -114,6 +114,10 @@ async def make_member(self, ctx: TeXBotApplicationContext, group_member_id: str) ), ephemeral=True, ) + logger.debug( + "User %s ran the makemember command but already had the member role!", + interaction_member, + ) return if not re.match(r"\A\d{7}\Z", group_member_id): @@ -145,6 +149,7 @@ async def make_member(self, ctx: TeXBotApplicationContext, group_member_id: str) ), ephemeral=True, ) + logger.debug("Student ID %s has already been used.", group_member_id) return guild_member_ids: set[str] = set() @@ -239,6 +244,7 @@ async def make_member(self, ctx: TeXBotApplicationContext, group_member_id: str) raise await ctx.respond("Successfully made you a member!", ephemeral=True) + logger.debug("User %s used the make member command successfully.", interaction_member) try: guest_role: discord.Role = await self.bot.guest_role @@ -254,6 +260,11 @@ async def make_member(self, ctx: TeXBotApplicationContext, group_member_id: str) guest_role, reason="TeX Bot slash-command: \"/makemember\"", ) + logger.debug( + "User %s has been given the Guest role as well as the " + "member role as they had not yet been inducted.", + interaction_member, + ) applicant_role: discord.Role | None = discord.utils.get( self.bot.main_guild.roles, @@ -264,3 +275,7 @@ async def make_member(self, ctx: TeXBotApplicationContext, group_member_id: str) applicant_role, reason="TeX Bot slash-command: \"/makemember\"", ) + logger.debug( + "Removed Applicant role from user %s after successful make member command", + interaction_member, + ) diff --git a/cogs/remind_me.py b/cogs/remind_me.py index 3505cef1..6bc26140 100644 --- a/cogs/remind_me.py +++ b/cogs/remind_me.py @@ -246,6 +246,7 @@ async def remind_me(self, ctx: TeXBotApplicationContext, delay: str, message: st return await ctx.respond("Reminder set!", ephemeral=True) + logger.debug("Reminder %s set for user %s", message, ctx.interaction.user) await discord.utils.sleep_until(reminder.send_datetime) diff --git a/cogs/send_get_roles_reminders.py b/cogs/send_get_roles_reminders.py index f6b40441..45f77784 100644 --- a/cogs/send_get_roles_reminders.py +++ b/cogs/send_get_roles_reminders.py @@ -172,6 +172,7 @@ async def send_get_roles_reminders(self) -> None: "and click on the icons to get optional roles like pronouns " "and year group identifiers.", ) + logger.debug("Role reminder sent to %s", member) except discord.Forbidden: logger.info( "Failed to open DM channel to user, %s, so no role reminder was sent.", diff --git a/cogs/send_introduction_reminders.py b/cogs/send_introduction_reminders.py index 80394599..66f0d2ce 100644 --- a/cogs/send_introduction_reminders.py +++ b/cogs/send_introduction_reminders.py @@ -163,6 +163,7 @@ async def send_introduction_reminders(self) -> None: else None # type: ignore[arg-type] ), ) + logger.debug("Sent introduction reminder to %s", member) except discord.Forbidden: logger.info( "Failed to open DM channel with user, %s, " @@ -269,6 +270,7 @@ async def opt_out_introduction_reminders_button_callback(self, button: discord.B await IntroductionReminderOptOutMember.objects.acreate( discord_id=interaction_member.id, ) + logger.debug("Created opt out object for user %s", interaction_member) except ValidationError as create_introduction_reminder_opt_out_member_error: error_is_already_exists: bool = ( "hashed_member_id" in create_introduction_reminder_opt_out_member_error.message_dict # noqa: E501 diff --git a/cogs/strike.py b/cogs/strike.py index a6147a10..597d54ab 100644 --- a/cogs/strike.py +++ b/cogs/strike.py @@ -17,8 +17,10 @@ import asyncio import contextlib import datetime +import logging import re from collections.abc import Mapping +from logging import Logger from typing import Final import aiohttp @@ -53,6 +55,8 @@ ResponseMessageSender, ) +logger: Logger = logging.getLogger("TeX-Bot") + async def perform_moderation_action(strike_user: discord.Member, strikes: int, committee_member: discord.Member | discord.User) -> None: # noqa: E501 """ @@ -80,9 +84,17 @@ async def perform_moderation_action(strike_user: discord.Member, strikes: int, c elif strikes == 2: await strike_user.kick(reason=MODERATION_ACTION_REASON) + logger.debug( + "User %s has been automatically kicked for having 2 strikes.", + strike_user, + ) elif strikes == 3: await strike_user.ban(reason=MODERATION_ACTION_REASON) + logger.debug( + "User %s has been automatically banned for having 3 strikes.", + strike_user, + ) class ConfirmStrikeMemberView(View): @@ -102,6 +114,7 @@ async def yes_strike_member_button_callback(self, _: discord.Button, interaction The actual handling of the event is done by the command that sent the view, so all that is required is to delete the original message that sent this view. """ + logger.debug("Confirm strike button pressed.") await interaction.response.edit_message(view=None) @discord.ui.button( # type: ignore[misc] @@ -118,6 +131,7 @@ async def no_strike_member_button_callback(self, _: discord.Button, interaction: The actual handling of the event is done by the command that sent the view, so all that is required is to delete the original message that sent this view. """ + logger.debug("Cancel strike button pressed.") await interaction.response.edit_message(view=None) @@ -139,6 +153,7 @@ async def yes_manual_moderation_action_button_callback(self, _: discord.Button, the manual moderation tracker subroutine that sent the view, so all that is required is to delete the original message that sent this view. """ + logger.debug("Confirm manual moderation action button pressed.") await interaction.response.edit_message(view=None) @discord.ui.button( # type: ignore[misc] @@ -156,6 +171,7 @@ async def no_manual_moderation_action_button_callback(self, _: discord.Button, i the manual moderation tracker subroutine that sent the view, so all that is required is to delete the original message that sent this view. """ + logger.debug("Cancel manual moderation action button pressed.") await interaction.response.edit_message(view=None) @@ -177,6 +193,7 @@ async def yes_out_of_sync_ban_member_button_callback(self, _: discord.Button, in the manual moderation tracker subroutine that sent the view, so all that is required is to delete the original message that sent this view. """ + logger.debug("Confirm out of sync ban member.") await interaction.response.edit_message(view=None) @discord.ui.button( # type: ignore[misc] @@ -194,6 +211,7 @@ async def no_out_of_sync_ban_member_button_callback(self, _: discord.Button, int the manual moderation tracker subroutine that sent the view, so all that is required is to delete the original message that sent this view. """ + logger.debug("Cancel out of sync ban member.") await interaction.response.edit_message(view=None) @@ -243,6 +261,7 @@ async def _send_strike_user_message(self, strike_user: discord.User | discord.Me f"to them.{includes_ban_message}\n\nA committee member will be in contact " "with you shortly, to discuss this further.", ) + logger.debug("Sent strike message to user %s", strike_user) async def _confirm_perform_moderation_action(self, message_sender_component: MessageSenderComponent, interaction_user: discord.User, strike_user: discord.Member, confirm_strike_message: str, actual_strike_amount: int, button_callback_channel: discord.TextChannel | discord.DMChannel) -> None: # noqa: E501 await message_sender_component.send( @@ -269,6 +288,7 @@ async def _confirm_perform_moderation_action(self, message_sender_component: Mes f"on {strike_user.mention}." ), ) + logger.debug("Cancelled strike action.") return if button_interaction.data["custom_id"] == "yes_strike_member": # type: ignore[index, typeddict-item] @@ -284,6 +304,7 @@ async def _confirm_perform_moderation_action(self, message_sender_component: Mes f"action on {strike_user.mention}." ), ) + logger.debug("Strike action against %s completed successfully.", strike_user) return raise ValueError @@ -340,6 +361,7 @@ async def _confirm_increase_strike(self, message_sender_component: MessageSender }""" ), ) + logger.debug("Sent strike confirmation message.") await asyncio.sleep(118) await message_sender_component.delete() return diff --git a/cogs/write_roles.py b/cogs/write_roles.py index f209e0b1..899a8952 100644 --- a/cogs/write_roles.py +++ b/cogs/write_roles.py @@ -5,11 +5,16 @@ __all__: Sequence[str] = ("WriteRolesCommandCog",) +import logging +from logging import Logger + import discord from config import settings from utils import CommandChecks, TeXBotApplicationContext, TeXBotBaseCog +logger: Logger = logging.getLogger("TeX-Bot") + class WriteRolesCommandCog(TeXBotBaseCog): # noinspection SpellCheckingInspection @@ -39,3 +44,4 @@ async def write_roles(self, ctx: TeXBotApplicationContext) -> None: ) await ctx.respond("All messages sent successfully.", ephemeral=True) + logger.debug("Sent role messages!") From f91d9b6de20220f9e2655be90f7243601045a9f7 Mon Sep 17 00:00:00 2001 From: MattyTheHacker <18513864+MattyTheHacker@users.noreply.github.com> Date: Mon, 27 May 2024 21:56:48 +0100 Subject: [PATCH 4/9] ruff deez nuts --- cogs/make_member.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/make_member.py b/cogs/make_member.py index 224b5eff..0814f2c3 100644 --- a/cogs/make_member.py +++ b/cogs/make_member.py @@ -94,7 +94,7 @@ class MakeMemberCommandCog(TeXBotBaseCog): parameter_name="group_member_id", ) @CommandChecks.check_interaction_user_in_main_guild - async def make_member(self, ctx: TeXBotApplicationContext, group_member_id: str) -> None: + async def make_member(self, ctx: TeXBotApplicationContext, group_member_id: str) -> None: # noqa: PLR0915 """ Definition & callback response of the "make_member" command. From 372d1a200104b59a60fa145f4cc8f275891c64b9 Mon Sep 17 00:00:00 2001 From: MattyTheHacker <18513864+MattyTheHacker@users.noreply.github.com> Date: Tue, 4 Jun 2024 12:47:59 +0100 Subject: [PATCH 5/9] change redundant debug messages --- cogs/archive.py | 2 +- cogs/induct.py | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/cogs/archive.py b/cogs/archive.py index 233e6d5c..8a0c0b7d 100644 --- a/cogs/archive.py +++ b/cogs/archive.py @@ -105,7 +105,7 @@ async def archive(self, ctx: TeXBotApplicationContext, str_category_id: str) -> ctx, message=f"Category with ID {str(category_id)!r} does not exist.", ) - logger.debug("Category with ID: %s could not be found!", str(category_id)) + logger.debug("Command execution terminated with the above error.") return if "archive" in category.name: diff --git a/cogs/induct.py b/cogs/induct.py index 7232ee63..15361bc1 100644 --- a/cogs/induct.py +++ b/cogs/induct.py @@ -202,10 +202,7 @@ async def _perform_induction(self, ctx: TeXBotApplicationContext, induction_memb ctx, message="Member cannot be inducted because they are a bot.", ) - logger.debug( - "Member %s could not be inducted because they are a bot.", - induction_member, - ) + logger.debug("Command execution terminated with the above error.") return if guest_role in induction_member.roles: From 3816625052216113c895d7494503b2a7fd66510d Mon Sep 17 00:00:00 2001 From: Matt Norton Date: Sat, 15 Jun 2024 13:21:03 +0100 Subject: [PATCH 6/9] Remove repeated code --- cogs/__init__.py | 3 +++ cogs/archive.py | 17 +---------------- cogs/command_success.py | 21 +++++++++++++++++++++ utils/tex_bot_base_cog.py | 20 ++++++++++++++++++++ 4 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 cogs/command_success.py diff --git a/cogs/__init__.py b/cogs/__init__.py index fe2fa808..4348b67d 100644 --- a/cogs/__init__.py +++ b/cogs/__init__.py @@ -11,6 +11,7 @@ "ArchiveCommandCog", "GetTokenAuthorisationCommand", "CommandErrorCog", + "CommandSuccessCog", "DeleteAllCommandsCog", "EditMessageCommandCog", "EnsureMembersInductedCommandCog", @@ -41,6 +42,7 @@ from cogs.archive import ArchiveCommandCog from cogs.command_error import CommandErrorCog +from cogs.command_success import CommandSuccessCog from cogs.delete_all import DeleteAllCommandsCog from cogs.edit_message import EditMessageCommandCog from cogs.get_token_authorisation import GetTokenAuthorisationCommand @@ -76,6 +78,7 @@ def setup(bot: TeXBot) -> None: ArchiveCommandCog, GetTokenAuthorisationCommand, CommandErrorCog, + CommandSuccessCog, DeleteAllCommandsCog, EditMessageCommandCog, EnsureMembersInductedCommandCog, diff --git a/cogs/archive.py b/cogs/archive.py index 8a0c0b7d..924910f1 100644 --- a/cogs/archive.py +++ b/cogs/archive.py @@ -105,7 +105,6 @@ async def archive(self, ctx: TeXBotApplicationContext, str_category_id: str) -> ctx, message=f"Category with ID {str(category_id)!r} does not exist.", ) - logger.debug("Command execution terminated with the above error.") return if "archive" in category.name: @@ -116,10 +115,7 @@ async def archive(self, ctx: TeXBotApplicationContext, str_category_id: str) -> ), ephemeral=True, ) - logger.debug( - "Category %s was already archived when the archive command was run", - category.name, - ) + self.log_user_error(f"Category {category.name} was already archived") return # noinspection PyUnreachableCode @@ -198,10 +194,6 @@ async def archive(self, ctx: TeXBotApplicationContext, str_category_id: str) -> ctx, message=f"Channel {channel.mention} had invalid permissions", ) - logger.error( - "Channel %s had invalid permissions, so could not be archived.", - channel.name, - ) return except discord.Forbidden: @@ -211,13 +203,6 @@ async def archive(self, ctx: TeXBotApplicationContext, str_category_id: str) -> "Bot does not have access to the channels in the selected category." ), ) - logger.error( # noqa: TRY400 - ( - "Bot did not have access to the channels in the selected category: " - "%s." - ), - category.name, - ) return await ctx.respond("Category successfully archived", ephemeral=True) diff --git a/cogs/command_success.py b/cogs/command_success.py new file mode 100644 index 00000000..ebd0f1e6 --- /dev/null +++ b/cogs/command_success.py @@ -0,0 +1,21 @@ +"""Contains cog classes for any command_success interactions.""" + +from collections.abc import Sequence + +__all__: Sequence[str] = ("CommandSuccessCog",) + + +import logging +from logging import Logger + +from utils import TeXBotApplicationContext, TeXBotBaseCog + +logger: Logger = logging.getLogger("TeX-Bot") + + +class CommandSuccessCog(TeXBotBaseCog): + """Cog class that defines additional code to execute upon a command success.""" + + @TeXBotBaseCog.listener() + async def on_application_command_completion(self, ctx: TeXBotApplicationContext) -> None: # TODO: Check not run on failure + logger.debug("Command execution complete.") # TODO: Pass command name to logger's extra diff --git a/utils/tex_bot_base_cog.py b/utils/tex_bot_base_cog.py index b59983ce..57c6e8b2 100644 --- a/utils/tex_bot_base_cog.py +++ b/utils/tex_bot_base_cog.py @@ -147,6 +147,26 @@ async def send_error(cls, bot: TeXBot, interaction: discord.Interaction, interac ).rstrip(": ;"), ) + elif error_code or message: + cls.log_user_error(error_code, message) + + @classmethod + def log_user_error(cls, error_code: str | None = None, message: str | None = None) -> None: + if not error_code and not message: + MISSING_ALL_PARAMETERS_MESSAGE: Final[str] = ( + "At least one of 'error_code' or 'message' parameters must be provided " + "to log_user_error()." + ) + raise ValueError(MISSING_ALL_PARAMETERS_MESSAGE) + + logger.debug( + "User error%s", + ( + f"{f" ({error_code})" if error_code else ""}" + f"{f": {message}" if message else ""}" + ), + ) + @staticmethod async def autocomplete_get_text_channels(ctx: TeXBotAutocompleteContext) -> set[discord.OptionChoice]: # noqa: E501 """ From 3c9dea66ab61dcc438dbf966e62681035e0ffc4d Mon Sep 17 00:00:00 2001 From: Matt Norton Date: Sat, 15 Jun 2024 13:21:46 +0100 Subject: [PATCH 7/9] Add TODO --- cogs/archive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/archive.py b/cogs/archive.py index 924910f1..d5a73327 100644 --- a/cogs/archive.py +++ b/cogs/archive.py @@ -20,7 +20,7 @@ TeXBotBaseCog, ) -logger: Logger = logging.getLogger("TeX-Bot") +logger: Logger = logging.getLogger("TeX-Bot") # TODO: Make logger with command name in formatter class ArchiveCommandCog(TeXBotBaseCog): From 7e8e1875aef0f78a020089cb251b597137a52432 Mon Sep 17 00:00:00 2001 From: Matt Norton Date: Sat, 15 Jun 2024 13:45:03 +0100 Subject: [PATCH 8/9] Fix duplicated logging messages --- cogs/archive.py | 2 +- cogs/edit_message.py | 8 -------- cogs/induct.py | 23 ++++++++++++++--------- cogs/make_member.py | 17 +++++++++++------ cogs/remind_me.py | 6 +++++- utils/tex_bot_base_cog.py | 4 ++-- 6 files changed, 33 insertions(+), 27 deletions(-) diff --git a/cogs/archive.py b/cogs/archive.py index d5a73327..8056cfc6 100644 --- a/cogs/archive.py +++ b/cogs/archive.py @@ -115,7 +115,7 @@ async def archive(self, ctx: TeXBotApplicationContext, str_category_id: str) -> ), ephemeral=True, ) - self.log_user_error(f"Category {category.name} was already archived") + self.log_user_error(message=f"Category {category.name} was already archived") return # noinspection PyUnreachableCode diff --git a/cogs/edit_message.py b/cogs/edit_message.py index 689d6b83..a807049a 100644 --- a/cogs/edit_message.py +++ b/cogs/edit_message.py @@ -97,7 +97,6 @@ async def edit_message(self, ctx: TeXBotApplicationContext, str_channel_id: str, ctx, message=f"{str_channel_id!r} is not a valid channel ID.", ) - logger.debug("Channel ID %s was not valid.", str_channel_id) return channel_id: int = int(str_channel_id) @@ -107,7 +106,6 @@ async def edit_message(self, ctx: TeXBotApplicationContext, str_channel_id: str, ctx, message=f"{str_message_id!r} is not a valid message ID.", ) - logger.debug("Message ID %s was not valid.", str_message_id) return message_id: int = int(str_message_id) @@ -121,7 +119,6 @@ async def edit_message(self, ctx: TeXBotApplicationContext, str_channel_id: str, ctx, message=f"Text channel with ID \"{channel_id}\" does not exist.", ) - logger.debug("Channel ID %s is not a text channel.", channel_id) return try: @@ -131,7 +128,6 @@ async def edit_message(self, ctx: TeXBotApplicationContext, str_channel_id: str, ctx, message=f"Message with ID \"{message_id}\" does not exist.", ) - logger.debug("Message ID %s could not be found.", message_id) return try: @@ -144,10 +140,6 @@ async def edit_message(self, ctx: TeXBotApplicationContext, str_channel_id: str, "because it belongs to another user." ), ) - logger.debug( - "Message ID %s does not belong to the bot, so could not be edited.", - message_id, - ) return else: await ctx.respond("Message edited successfully.", ephemeral=True) diff --git a/cogs/induct.py b/cogs/induct.py index 6fbbcd9c..c6330797 100644 --- a/cogs/induct.py +++ b/cogs/induct.py @@ -202,7 +202,6 @@ async def _perform_induction(self, ctx: TeXBotApplicationContext, induction_memb ctx, message="Member cannot be inducted because they are a bot.", ) - logger.debug("Command execution terminated with the above error.") return if guest_role in induction_member.roles: @@ -212,9 +211,11 @@ async def _perform_induction(self, ctx: TeXBotApplicationContext, induction_memb "User has already been inducted. :information_source:" ), ) - logger.debug( - "User %s was not inducted because they already have the guest role.", - induction_member, + self.log_user_error( + message=( + f"User {induction_member} was not inducted " + f"because they already have the guest role." + ), ) return @@ -288,7 +289,10 @@ async def _perform_induction(self, ctx: TeXBotApplicationContext, induction_memb break await initial_response.edit(content=":white_check_mark: User inducted successfully.") - logger.debug("Induction completed successfully for user %s", induction_member) + logger.debug( + "Induction completed successfully for user %s", + induction_member, + ) class InductSlashCommandCog(BaseInductCog): @@ -507,7 +511,8 @@ async def ensure_members_inducted(self, ctx: TeXBotApplicationContext) -> None: ), ephemeral=True, ) - if changes_made: - logger.debug("Successfully inducted members.") - else: - logger.debug("No members have been inducted. ") + logger.debug( + "Successfully inducted members" + if changes_made + else "No members have been inducted" # noqa: COM812 + ) diff --git a/cogs/make_member.py b/cogs/make_member.py index 599aea14..9e128123 100644 --- a/cogs/make_member.py +++ b/cogs/make_member.py @@ -118,9 +118,8 @@ async def make_member(self, ctx: TeXBotApplicationContext, group_member_id: str) ), ephemeral=True, ) - logger.debug( - "User %s ran the makemember command but already had the member role!", - interaction_member, + self.log_user_error( + message=f"User {interaction_member} already had the member role!", ) return @@ -153,7 +152,7 @@ async def make_member(self, ctx: TeXBotApplicationContext, group_member_id: str) ), ephemeral=True, ) - logger.debug("Student ID %s has already been used.", group_member_id) + self.log_user_error(message=f"Student ID {group_member_id} has already been used.") return guild_member_ids: set[str] = set() @@ -248,7 +247,10 @@ async def make_member(self, ctx: TeXBotApplicationContext, group_member_id: str) raise await ctx.respond("Successfully made you a member!", ephemeral=True) - logger.debug("User %s used the make member command successfully.", interaction_member) + logger.debug( + "User %s used the make member command successfully.", + interaction_member, + ) try: guest_role: discord.Role = await self.bot.guest_role @@ -270,6 +272,7 @@ async def make_member(self, ctx: TeXBotApplicationContext, group_member_id: str) interaction_member, ) + # noinspection PyUnusedLocal applicant_role: discord.Role | None = None with contextlib.suppress(ApplicantRoleDoesNotExistError): applicant_role = await ctx.bot.applicant_role @@ -280,6 +283,8 @@ async def make_member(self, ctx: TeXBotApplicationContext, group_member_id: str) reason="TeX Bot slash-command: \"/makemember\"", ) logger.debug( - "Removed Applicant role from user %s after successful make member command", + ( + "Removed Applicant role from user %s after successful make-member command" + ), interaction_member, ) diff --git a/cogs/remind_me.py b/cogs/remind_me.py index 6bc26140..59402704 100644 --- a/cogs/remind_me.py +++ b/cogs/remind_me.py @@ -246,7 +246,11 @@ async def remind_me(self, ctx: TeXBotApplicationContext, delay: str, message: st return await ctx.respond("Reminder set!", ephemeral=True) - logger.debug("Reminder %s set for user %s", message, ctx.interaction.user) + logger.debug( + "Reminder '%s' set for user %s", + f"{message[:15]}..." if len(message) > 15 else message, + ctx.interaction.user, + ) await discord.utils.sleep_until(reminder.send_datetime) diff --git a/utils/tex_bot_base_cog.py b/utils/tex_bot_base_cog.py index 57c6e8b2..918d558c 100644 --- a/utils/tex_bot_base_cog.py +++ b/utils/tex_bot_base_cog.py @@ -148,10 +148,10 @@ async def send_error(cls, bot: TeXBot, interaction: discord.Interaction, interac ) elif error_code or message: - cls.log_user_error(error_code, message) + cls.log_user_error(error_code=error_code, message=message) @classmethod - def log_user_error(cls, error_code: str | None = None, message: str | None = None) -> None: + def log_user_error(cls, *, error_code: str | None = None, message: str | None = None) -> None: if not error_code and not message: MISSING_ALL_PARAMETERS_MESSAGE: Final[str] = ( "At least one of 'error_code' or 'message' parameters must be provided " From 89776a02c654c9accfaa2e20f801e7dfa1a0b97f Mon Sep 17 00:00:00 2001 From: Matt Norton Date: Sat, 15 Jun 2024 13:48:40 +0100 Subject: [PATCH 9/9] Remove incorrect TODOs --- cogs/archive.py | 2 +- cogs/command_success.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/archive.py b/cogs/archive.py index 8056cfc6..3cd50370 100644 --- a/cogs/archive.py +++ b/cogs/archive.py @@ -20,7 +20,7 @@ TeXBotBaseCog, ) -logger: Logger = logging.getLogger("TeX-Bot") # TODO: Make logger with command name in formatter +logger: Logger = logging.getLogger("TeX-Bot") class ArchiveCommandCog(TeXBotBaseCog): diff --git a/cogs/command_success.py b/cogs/command_success.py index ebd0f1e6..3e04844c 100644 --- a/cogs/command_success.py +++ b/cogs/command_success.py @@ -17,5 +17,5 @@ class CommandSuccessCog(TeXBotBaseCog): """Cog class that defines additional code to execute upon a command success.""" @TeXBotBaseCog.listener() - async def on_application_command_completion(self, ctx: TeXBotApplicationContext) -> None: # TODO: Check not run on failure + async def on_application_command_completion(self, ctx: TeXBotApplicationContext) -> None: logger.debug("Command execution complete.") # TODO: Pass command name to logger's extra