Repository: python-discord/bot

Issue:
Log full traceback with `log.exception` in exception handlers
While trying to reload the `reddit` cog, I noticed that the `cogs` cog doesn't log the full traceback in the `except` blocks, but just the exception message using `log.error`. It would be better to use `log.exception` here to make sure that the full traceback is included instead of just a message like ` 'NoneType' object has no attribute 'startswith'`. (`log.exception` automatically includes the full traceback when used in an exception handler, no additional arguments required.)

I suspect that more cogs do this, so I think it's a good idea to check all the cogs after the Django migration is completed to change the log methods to `log.exception` inside exception handlers where appropriate.

Example from the `cogs` cog (it's both in `master` and `django`):
https://github.com/python-discord/bot/blob/5e16f4a52d59c73a04323e070e7b4a320e8c1e49/bot/cogs/cogs.py#L85
https://github.com/python-discord/bot/blob/25640adec9d042ccf249a91540fb09d354b04dfd/bot/cogs/cogs.py#L85


Discussion:

Resolving patch:
diff --git a/bot/cogs/cogs.py b/bot/cogs/cogs.py
--- a/bot/cogs/cogs.py
+++ b/bot/cogs/cogs.py
@@ -74,13 +74,12 @@ async def load_command(self, ctx: Context, cog: str) -> None:
                 try:
                     self.bot.load_extension(full_cog)
                 except ImportError:
-                    log.error(f"{ctx.author} requested we load the '{cog}' cog, "
-                              f"but the cog module {full_cog} could not be found!")
+                    log.exception(f"{ctx.author} requested we load the '{cog}' cog, "
+                                  f"but the cog module {full_cog} could not be found!")
                     embed.description = f"Invalid cog: {cog}\n\nCould not find cog module {full_cog}"
                 except Exception as e:
-                    log.error(f"{ctx.author} requested we load the '{cog}' cog, "
-                              "but the loading failed with the following error: \n"
-                              f"**{e.__class__.__name__}: {e}**")
+                    log.exception(f"{ctx.author} requested we load the '{cog}' cog, "
+                                  "but the loading failed")
                     embed.description = f"Failed to load cog: {cog}\n\n{e.__class__.__name__}: {e}"
                 else:
                     log.debug(f"{ctx.author} requested we load the '{cog}' cog. Cog loaded!")
@@ -129,9 +128,8 @@ async def unload_command(self, ctx: Context, cog: str) -> None:
                 try:
                     self.bot.unload_extension(full_cog)
                 except Exception as e:
-                    log.error(f"{ctx.author} requested we unload the '{cog}' cog, "
-                              "but the unloading failed with the following error: \n"
-                              f"{e}")
+                    log.exception(f"{ctx.author} requested we unload the '{cog}' cog, "
+                                  "but the unloading failed")
                     embed.description = f"Failed to unload cog: {cog}\n\n```{e}```"
                 else:
                     log.debug(f"{ctx.author} requested we unload the '{cog}' cog. Cog unloaded!")
@@ -234,9 +232,8 @@ async def reload_command(self, ctx: Context, cog: str) -> None:
                     self.bot.unload_extension(full_cog)
                     self.bot.load_extension(full_cog)
                 except Exception as e:
-                    log.error(f"{ctx.author} requested we reload the '{cog}' cog, "
-                              "but the unloading failed with the following error: \n"
-                              f"{e}")
+                    log.exception(f"{ctx.author} requested we reload the '{cog}' cog, "
+                                  "but the unloading failed")
                     embed.description = f"Failed to reload cog: {cog}\n\n```{e}```"
                 else:
                     log.debug(f"{ctx.author} requested we reload the '{cog}' cog. Cog reloaded!")


Test patch: