We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Tag fallback bypasses the bot's DM restrictions
When a user issues a command that does not exist, we fall back to trying to match it as a tag name. This means that a message containing `!f-strings`, which is not a command in itself, will result in the bot sending the contents of the `f-strings` tag. This is a great feature, but it currently does not respect the DM-restriction we've put in place: Members should only be able to issue commands in public channels, not a DM conversation with the bot.

The [current code responsible for the tag fallback](https://github.com/python-discord/bot/blob/master/bot/cogs/error_handler.py#L73) only checks if the user is not issuing the pseudo-command in checkpoint. The global checks that prevent commands from being issued in DMs are [defined in the security cog](https://github.com/python-discord/bot/blob/master/bot/cogs/security.py).

#### Bot response after command in DM

![command_in_dm](https://user-images.githubusercontent.com/33516116/68120021-923e0180-ff04-11e9-90f4-ac6c0043d98d.png)

#### Bot response after tag in DM

![tag_in_dm](https://user-images.githubusercontent.com/33516116/68120036-99fda600-ff04-11e9-8cb4-6583e7cfd5ad.png)

Tag fallback bypasses the bot's DM restrictions
When a user issues a command that does not exist, we fall back to trying to match it as a tag name. This means that a message containing `!f-strings`, which is not a command in itself, will result in the bot sending the contents of the `f-strings` tag. This is a great feature, but it currently does not respect the DM-restriction we've put in place: Members should only be able to issue commands in public channels, not a DM conversation with the bot.

The [current code responsible for the tag fallback](https://github.com/python-discord/bot/blob/master/bot/cogs/error_handler.py#L73) only checks if the user is not issuing the pseudo-command in checkpoint. The global checks that prevent commands from being issued in DMs are [defined in the security cog](https://github.com/python-discord/bot/blob/master/bot/cogs/security.py).

#### Bot response after command in DM

![command_in_dm](https://user-images.githubusercontent.com/33516116/68120021-923e0180-ff04-11e9-90f4-ac6c0043d98d.png)

#### Bot response after tag in DM

![tag_in_dm](https://user-images.githubusercontent.com/33516116/68120036-99fda600-ff04-11e9-8cb4-6583e7cfd5ad.png)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `bot/cogs/error_handler.py`
Content:
```
1 import contextlib
2 import logging
3 
4 from discord.ext.commands import (
5     BadArgument,
6     BotMissingPermissions,
7     CheckFailure,
8     CommandError,
9     CommandInvokeError,
10     CommandNotFound,
11     CommandOnCooldown,
12     DisabledCommand,
13     MissingPermissions,
14     NoPrivateMessage,
15     UserInputError,
16 )
17 from discord.ext.commands import Bot, Cog, Context
18 
19 from bot.api import ResponseCodeError
20 from bot.constants import Channels
21 from bot.decorators import InChannelCheckFailure
22 
23 log = logging.getLogger(__name__)
24 
25 
26 class ErrorHandler(Cog):
27     """Handles errors emitted from commands."""
28 
29     def __init__(self, bot: Bot):
30         self.bot = bot
31 
32     @Cog.listener()
33     async def on_command_error(self, ctx: Context, e: CommandError) -> None:
34         """
35         Provide generic command error handling.
36 
37         Error handling is deferred to any local error handler, if present.
38 
39         Error handling emits a single error response, prioritized as follows:
40             1. If the name fails to match a command but matches a tag, the tag is invoked
41             2. Send a BadArgument error message to the invoking context & invoke the command's help
42             3. Send a UserInputError error message to the invoking context & invoke the command's help
43             4. Send a NoPrivateMessage error message to the invoking context
44             5. Send a BotMissingPermissions error message to the invoking context
45             6. Log a MissingPermissions error, no message is sent
46             7. Send a InChannelCheckFailure error message to the invoking context
47             8. Log CheckFailure, CommandOnCooldown, and DisabledCommand errors, no message is sent
48             9. For CommandInvokeErrors, response is based on the type of error:
49                 * 404: Error message is sent to the invoking context
50                 * 400: Log the resopnse JSON, no message is sent
51                 * 500 <= status <= 600: Error message is sent to the invoking context
52             10. Otherwise, handling is deferred to `handle_unexpected_error`
53         """
54         command = ctx.command
55         parent = None
56 
57         if command is not None:
58             parent = command.parent
59 
60         # Retrieve the help command for the invoked command.
61         if parent and command:
62             help_command = (self.bot.get_command("help"), parent.name, command.name)
63         elif command:
64             help_command = (self.bot.get_command("help"), command.name)
65         else:
66             help_command = (self.bot.get_command("help"),)
67 
68         if hasattr(e, "handled"):
69             log.trace(f"Command {command} had its error already handled locally; ignoring.")
70             return
71 
72         # Try to look for a tag with the command's name if the command isn't found.
73         if isinstance(e, CommandNotFound) and not hasattr(ctx, "invoked_from_error_handler"):
74             if not ctx.channel.id == Channels.verification:
75                 tags_get_command = self.bot.get_command("tags get")
76                 ctx.invoked_from_error_handler = True
77 
78                 # Return to not raise the exception
79                 with contextlib.suppress(ResponseCodeError):
80                     await ctx.invoke(tags_get_command, tag_name=ctx.invoked_with)
81                     return
82         elif isinstance(e, BadArgument):
83             await ctx.send(f"Bad argument: {e}\n")
84             await ctx.invoke(*help_command)
85         elif isinstance(e, UserInputError):
86             await ctx.send("Something about your input seems off. Check the arguments:")
87             await ctx.invoke(*help_command)
88             log.debug(
89                 f"Command {command} invoked by {ctx.message.author} with error "
90                 f"{e.__class__.__name__}: {e}"
91             )
92         elif isinstance(e, NoPrivateMessage):
93             await ctx.send("Sorry, this command can't be used in a private message!")
94         elif isinstance(e, BotMissingPermissions):
95             await ctx.send(f"Sorry, it looks like I don't have the permissions I need to do that.")
96             log.warning(
97                 f"The bot is missing permissions to execute command {command}: {e.missing_perms}"
98             )
99         elif isinstance(e, MissingPermissions):
100             log.debug(
101                 f"{ctx.message.author} is missing permissions to invoke command {command}: "
102                 f"{e.missing_perms}"
103             )
104         elif isinstance(e, InChannelCheckFailure):
105             await ctx.send(e)
106         elif isinstance(e, (CheckFailure, CommandOnCooldown, DisabledCommand)):
107             log.debug(
108                 f"Command {command} invoked by {ctx.message.author} with error "
109                 f"{e.__class__.__name__}: {e}"
110             )
111         elif isinstance(e, CommandInvokeError):
112             if isinstance(e.original, ResponseCodeError):
113                 status = e.original.response.status
114 
115                 if status == 404:
116                     await ctx.send("There does not seem to be anything matching your query.")
117                 elif status == 400:
118                     content = await e.original.response.json()
119                     log.debug(f"API responded with 400 for command {command}: %r.", content)
120                     await ctx.send("According to the API, your request is malformed.")
121                 elif 500 <= status < 600:
122                     await ctx.send("Sorry, there seems to be an internal issue with the API.")
123                     log.warning(f"API responded with {status} for command {command}")
124                 else:
125                     await ctx.send(f"Got an unexpected status code from the API (`{status}`).")
126                     log.warning(f"Unexpected API response for command {command}: {status}")
127             else:
128                 await self.handle_unexpected_error(ctx, e.original)
129         else:
130             await self.handle_unexpected_error(ctx, e)
131 
132     @staticmethod
133     async def handle_unexpected_error(ctx: Context, e: CommandError) -> None:
134         """Generic handler for errors without an explicit handler."""
135         await ctx.send(
136             f"Sorry, an unexpected error occurred. Please let us know!\n\n"
137             f"```{e.__class__.__name__}: {e}```"
138         )
139         log.error(
140             f"Error executing command invoked by {ctx.message.author}: {ctx.message.content}"
141         )
142         raise e
143 
144 
145 def setup(bot: Bot) -> None:
146     """Error handler cog load."""
147     bot.add_cog(ErrorHandler(bot))
148     log.info("Cog loaded: Events")
149
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/bot/cogs/error_handler.py b/bot/cogs/error_handler.py
--- a/bot/cogs/error_handler.py
+++ b/bot/cogs/error_handler.py
@@ -75,6 +75,16 @@
                 tags_get_command = self.bot.get_command("tags get")
                 ctx.invoked_from_error_handler = True
 
+                log_msg = "Cancelling attempt to fall back to a tag due to failed checks."
+                try:
+                    if not await tags_get_command.can_run(ctx):
+                        log.debug(log_msg)
+                        return
+                except CommandError as tag_error:
+                    log.debug(log_msg)
+                    await self.on_command_error(ctx, tag_error)
+                    return
+
                 # Return to not raise the exception
                 with contextlib.suppress(ResponseCodeError):
                     await ctx.invoke(tags_get_command, tag_name=ctx.invoked_with)

{"golden_diff": "diff --git a/bot/cogs/error_handler.py b/bot/cogs/error_handler.py\n--- a/bot/cogs/error_handler.py\n+++ b/bot/cogs/error_handler.py\n@@ -75,6 +75,16 @@\n                 tags_get_command = self.bot.get_command(\"tags get\")\n                 ctx.invoked_from_error_handler = True\n \n+                log_msg = \"Cancelling attempt to fall back to a tag due to failed checks.\"\n+                try:\n+                    if not await tags_get_command.can_run(ctx):\n+                        log.debug(log_msg)\n+                        return\n+                except CommandError as tag_error:\n+                    log.debug(log_msg)\n+                    await self.on_command_error(ctx, tag_error)\n+                    return\n+\n                 # Return to not raise the exception\n                 with contextlib.suppress(ResponseCodeError):\n                     await ctx.invoke(tags_get_command, tag_name=ctx.invoked_with)\n", "issue": "Tag fallback bypasses the bot's DM restrictions\nWhen a user issues a command that does not exist, we fall back to trying to match it as a tag name. This means that a message containing `!f-strings`, which is not a command in itself, will result in the bot sending the contents of the `f-strings` tag. This is a great feature, but it currently does not respect the DM-restriction we've put in place: Members should only be able to issue commands in public channels, not a DM conversation with the bot.\r\n\r\nThe [current code responsible for the tag fallback](https://github.com/python-discord/bot/blob/master/bot/cogs/error_handler.py#L73) only checks if the user is not issuing the pseudo-command in checkpoint. The global checks that prevent commands from being issued in DMs are [defined in the security cog](https://github.com/python-discord/bot/blob/master/bot/cogs/security.py).\r\n\r\n#### Bot response after command in DM\r\n\r\n![command_in_dm](https://user-images.githubusercontent.com/33516116/68120021-923e0180-ff04-11e9-90f4-ac6c0043d98d.png)\r\n\r\n#### Bot response after tag in DM\r\n\r\n![tag_in_dm](https://user-images.githubusercontent.com/33516116/68120036-99fda600-ff04-11e9-8cb4-6583e7cfd5ad.png)\r\n\nTag fallback bypasses the bot's DM restrictions\nWhen a user issues a command that does not exist, we fall back to trying to match it as a tag name. This means that a message containing `!f-strings`, which is not a command in itself, will result in the bot sending the contents of the `f-strings` tag. This is a great feature, but it currently does not respect the DM-restriction we've put in place: Members should only be able to issue commands in public channels, not a DM conversation with the bot.\r\n\r\nThe [current code responsible for the tag fallback](https://github.com/python-discord/bot/blob/master/bot/cogs/error_handler.py#L73) only checks if the user is not issuing the pseudo-command in checkpoint. The global checks that prevent commands from being issued in DMs are [defined in the security cog](https://github.com/python-discord/bot/blob/master/bot/cogs/security.py).\r\n\r\n#### Bot response after command in DM\r\n\r\n![command_in_dm](https://user-images.githubusercontent.com/33516116/68120021-923e0180-ff04-11e9-90f4-ac6c0043d98d.png)\r\n\r\n#### Bot response after tag in DM\r\n\r\n![tag_in_dm](https://user-images.githubusercontent.com/33516116/68120036-99fda600-ff04-11e9-8cb4-6583e7cfd5ad.png)\r\n\n", "before_files": [{"content": "import contextlib\nimport logging\n\nfrom discord.ext.commands import (\n    BadArgument,\n    BotMissingPermissions,\n    CheckFailure,\n    CommandError,\n    CommandInvokeError,\n    CommandNotFound,\n    CommandOnCooldown,\n    DisabledCommand,\n    MissingPermissions,\n    NoPrivateMessage,\n    UserInputError,\n)\nfrom discord.ext.commands import Bot, Cog, Context\n\nfrom bot.api import ResponseCodeError\nfrom bot.constants import Channels\nfrom bot.decorators import InChannelCheckFailure\n\nlog = logging.getLogger(__name__)\n\n\nclass ErrorHandler(Cog):\n    \"\"\"Handles errors emitted from commands.\"\"\"\n\n    def __init__(self, bot: Bot):\n        self.bot = bot\n\n    @Cog.listener()\n    async def on_command_error(self, ctx: Context, e: CommandError) -> None:\n        \"\"\"\n        Provide generic command error handling.\n\n        Error handling is deferred to any local error handler, if present.\n\n        Error handling emits a single error response, prioritized as follows:\n            1. If the name fails to match a command but matches a tag, the tag is invoked\n            2. Send a BadArgument error message to the invoking context & invoke the command's help\n            3. Send a UserInputError error message to the invoking context & invoke the command's help\n            4. Send a NoPrivateMessage error message to the invoking context\n            5. Send a BotMissingPermissions error message to the invoking context\n            6. Log a MissingPermissions error, no message is sent\n            7. Send a InChannelCheckFailure error message to the invoking context\n            8. Log CheckFailure, CommandOnCooldown, and DisabledCommand errors, no message is sent\n            9. For CommandInvokeErrors, response is based on the type of error:\n                * 404: Error message is sent to the invoking context\n                * 400: Log the resopnse JSON, no message is sent\n                * 500 <= status <= 600: Error message is sent to the invoking context\n            10. Otherwise, handling is deferred to `handle_unexpected_error`\n        \"\"\"\n        command = ctx.command\n        parent = None\n\n        if command is not None:\n            parent = command.parent\n\n        # Retrieve the help command for the invoked command.\n        if parent and command:\n            help_command = (self.bot.get_command(\"help\"), parent.name, command.name)\n        elif command:\n            help_command = (self.bot.get_command(\"help\"), command.name)\n        else:\n            help_command = (self.bot.get_command(\"help\"),)\n\n        if hasattr(e, \"handled\"):\n            log.trace(f\"Command {command} had its error already handled locally; ignoring.\")\n            return\n\n        # Try to look for a tag with the command's name if the command isn't found.\n        if isinstance(e, CommandNotFound) and not hasattr(ctx, \"invoked_from_error_handler\"):\n            if not ctx.channel.id == Channels.verification:\n                tags_get_command = self.bot.get_command(\"tags get\")\n                ctx.invoked_from_error_handler = True\n\n                # Return to not raise the exception\n                with contextlib.suppress(ResponseCodeError):\n                    await ctx.invoke(tags_get_command, tag_name=ctx.invoked_with)\n                    return\n        elif isinstance(e, BadArgument):\n            await ctx.send(f\"Bad argument: {e}\\n\")\n            await ctx.invoke(*help_command)\n        elif isinstance(e, UserInputError):\n            await ctx.send(\"Something about your input seems off. Check the arguments:\")\n            await ctx.invoke(*help_command)\n            log.debug(\n                f\"Command {command} invoked by {ctx.message.author} with error \"\n                f\"{e.__class__.__name__}: {e}\"\n            )\n        elif isinstance(e, NoPrivateMessage):\n            await ctx.send(\"Sorry, this command can't be used in a private message!\")\n        elif isinstance(e, BotMissingPermissions):\n            await ctx.send(f\"Sorry, it looks like I don't have the permissions I need to do that.\")\n            log.warning(\n                f\"The bot is missing permissions to execute command {command}: {e.missing_perms}\"\n            )\n        elif isinstance(e, MissingPermissions):\n            log.debug(\n                f\"{ctx.message.author} is missing permissions to invoke command {command}: \"\n                f\"{e.missing_perms}\"\n            )\n        elif isinstance(e, InChannelCheckFailure):\n            await ctx.send(e)\n        elif isinstance(e, (CheckFailure, CommandOnCooldown, DisabledCommand)):\n            log.debug(\n                f\"Command {command} invoked by {ctx.message.author} with error \"\n                f\"{e.__class__.__name__}: {e}\"\n            )\n        elif isinstance(e, CommandInvokeError):\n            if isinstance(e.original, ResponseCodeError):\n                status = e.original.response.status\n\n                if status == 404:\n                    await ctx.send(\"There does not seem to be anything matching your query.\")\n                elif status == 400:\n                    content = await e.original.response.json()\n                    log.debug(f\"API responded with 400 for command {command}: %r.\", content)\n                    await ctx.send(\"According to the API, your request is malformed.\")\n                elif 500 <= status < 600:\n                    await ctx.send(\"Sorry, there seems to be an internal issue with the API.\")\n                    log.warning(f\"API responded with {status} for command {command}\")\n                else:\n                    await ctx.send(f\"Got an unexpected status code from the API (`{status}`).\")\n                    log.warning(f\"Unexpected API response for command {command}: {status}\")\n            else:\n                await self.handle_unexpected_error(ctx, e.original)\n        else:\n            await self.handle_unexpected_error(ctx, e)\n\n    @staticmethod\n    async def handle_unexpected_error(ctx: Context, e: CommandError) -> None:\n        \"\"\"Generic handler for errors without an explicit handler.\"\"\"\n        await ctx.send(\n            f\"Sorry, an unexpected error occurred. Please let us know!\\n\\n\"\n            f\"```{e.__class__.__name__}: {e}```\"\n        )\n        log.error(\n            f\"Error executing command invoked by {ctx.message.author}: {ctx.message.content}\"\n        )\n        raise e\n\n\ndef setup(bot: Bot) -> None:\n    \"\"\"Error handler cog load.\"\"\"\n    bot.add_cog(ErrorHandler(bot))\n    log.info(\"Cog loaded: Events\")\n", "path": "bot/cogs/error_handler.py"}], "after_files": [{"content": "import contextlib\nimport logging\n\nfrom discord.ext.commands import (\n    BadArgument,\n    BotMissingPermissions,\n    CheckFailure,\n    CommandError,\n    CommandInvokeError,\n    CommandNotFound,\n    CommandOnCooldown,\n    DisabledCommand,\n    MissingPermissions,\n    NoPrivateMessage,\n    UserInputError,\n)\nfrom discord.ext.commands import Bot, Cog, Context\n\nfrom bot.api import ResponseCodeError\nfrom bot.constants import Channels\nfrom bot.decorators import InChannelCheckFailure\n\nlog = logging.getLogger(__name__)\n\n\nclass ErrorHandler(Cog):\n    \"\"\"Handles errors emitted from commands.\"\"\"\n\n    def __init__(self, bot: Bot):\n        self.bot = bot\n\n    @Cog.listener()\n    async def on_command_error(self, ctx: Context, e: CommandError) -> None:\n        \"\"\"\n        Provide generic command error handling.\n\n        Error handling is deferred to any local error handler, if present.\n\n        Error handling emits a single error response, prioritized as follows:\n            1. If the name fails to match a command but matches a tag, the tag is invoked\n            2. Send a BadArgument error message to the invoking context & invoke the command's help\n            3. Send a UserInputError error message to the invoking context & invoke the command's help\n            4. Send a NoPrivateMessage error message to the invoking context\n            5. Send a BotMissingPermissions error message to the invoking context\n            6. Log a MissingPermissions error, no message is sent\n            7. Send a InChannelCheckFailure error message to the invoking context\n            8. Log CheckFailure, CommandOnCooldown, and DisabledCommand errors, no message is sent\n            9. For CommandInvokeErrors, response is based on the type of error:\n                * 404: Error message is sent to the invoking context\n                * 400: Log the resopnse JSON, no message is sent\n                * 500 <= status <= 600: Error message is sent to the invoking context\n            10. Otherwise, handling is deferred to `handle_unexpected_error`\n        \"\"\"\n        command = ctx.command\n        parent = None\n\n        if command is not None:\n            parent = command.parent\n\n        # Retrieve the help command for the invoked command.\n        if parent and command:\n            help_command = (self.bot.get_command(\"help\"), parent.name, command.name)\n        elif command:\n            help_command = (self.bot.get_command(\"help\"), command.name)\n        else:\n            help_command = (self.bot.get_command(\"help\"),)\n\n        if hasattr(e, \"handled\"):\n            log.trace(f\"Command {command} had its error already handled locally; ignoring.\")\n            return\n\n        # Try to look for a tag with the command's name if the command isn't found.\n        if isinstance(e, CommandNotFound) and not hasattr(ctx, \"invoked_from_error_handler\"):\n            if not ctx.channel.id == Channels.verification:\n                tags_get_command = self.bot.get_command(\"tags get\")\n                ctx.invoked_from_error_handler = True\n\n                log_msg = \"Cancelling attempt to fall back to a tag due to failed checks.\"\n                try:\n                    if not await tags_get_command.can_run(ctx):\n                        log.debug(log_msg)\n                        return\n                except CommandError as tag_error:\n                    log.debug(log_msg)\n                    await self.on_command_error(ctx, tag_error)\n                    return\n\n                # Return to not raise the exception\n                with contextlib.suppress(ResponseCodeError):\n                    await ctx.invoke(tags_get_command, tag_name=ctx.invoked_with)\n                    return\n        elif isinstance(e, BadArgument):\n            await ctx.send(f\"Bad argument: {e}\\n\")\n            await ctx.invoke(*help_command)\n        elif isinstance(e, UserInputError):\n            await ctx.send(\"Something about your input seems off. Check the arguments:\")\n            await ctx.invoke(*help_command)\n            log.debug(\n                f\"Command {command} invoked by {ctx.message.author} with error \"\n                f\"{e.__class__.__name__}: {e}\"\n            )\n        elif isinstance(e, NoPrivateMessage):\n            await ctx.send(\"Sorry, this command can't be used in a private message!\")\n        elif isinstance(e, BotMissingPermissions):\n            await ctx.send(f\"Sorry, it looks like I don't have the permissions I need to do that.\")\n            log.warning(\n                f\"The bot is missing permissions to execute command {command}: {e.missing_perms}\"\n            )\n        elif isinstance(e, MissingPermissions):\n            log.debug(\n                f\"{ctx.message.author} is missing permissions to invoke command {command}: \"\n                f\"{e.missing_perms}\"\n            )\n        elif isinstance(e, InChannelCheckFailure):\n            await ctx.send(e)\n        elif isinstance(e, (CheckFailure, CommandOnCooldown, DisabledCommand)):\n            log.debug(\n                f\"Command {command} invoked by {ctx.message.author} with error \"\n                f\"{e.__class__.__name__}: {e}\"\n            )\n        elif isinstance(e, CommandInvokeError):\n            if isinstance(e.original, ResponseCodeError):\n                status = e.original.response.status\n\n                if status == 404:\n                    await ctx.send(\"There does not seem to be anything matching your query.\")\n                elif status == 400:\n                    content = await e.original.response.json()\n                    log.debug(f\"API responded with 400 for command {command}: %r.\", content)\n                    await ctx.send(\"According to the API, your request is malformed.\")\n                elif 500 <= status < 600:\n                    await ctx.send(\"Sorry, there seems to be an internal issue with the API.\")\n                    log.warning(f\"API responded with {status} for command {command}\")\n                else:\n                    await ctx.send(f\"Got an unexpected status code from the API (`{status}`).\")\n                    log.warning(f\"Unexpected API response for command {command}: {status}\")\n            else:\n                await self.handle_unexpected_error(ctx, e.original)\n        else:\n            await self.handle_unexpected_error(ctx, e)\n\n    @staticmethod\n    async def handle_unexpected_error(ctx: Context, e: CommandError) -> None:\n        \"\"\"Generic handler for errors without an explicit handler.\"\"\"\n        await ctx.send(\n            f\"Sorry, an unexpected error occurred. Please let us know!\\n\\n\"\n            f\"```{e.__class__.__name__}: {e}```\"\n        )\n        log.error(\n            f\"Error executing command invoked by {ctx.message.author}: {ctx.message.content}\"\n        )\n        raise e\n\n\ndef setup(bot: Bot) -> None:\n    \"\"\"Error handler cog load.\"\"\"\n    bot.add_cog(ErrorHandler(bot))\n    log.info(\"Cog loaded: Events\")\n", "path": "bot/cogs/error_handler.py"}]}