diff --git a/bot/__main__.py b/bot/__main__.py
index bacb2fdd69..a6eb6d888c 100644
--- a/bot/__main__.py
+++ b/bot/__main__.py
@@ -11,12 +11,14 @@
 import bot
 from bot import constants
 from bot.bot import Bot
+from bot.command_error_handlers import bootstrap_command_error_manager
 from bot.log import setup_sentry
 from bot.utils.decorators import whitelist_check
 
 log = get_logger(__name__)
 setup_sentry()
 
+
 async def _create_redis_session() -> RedisSession:
     """Create and connect to a redis session."""
     redis_session = RedisSession(
@@ -74,6 +76,8 @@ async def main() -> None:
             allowed_roles=allowed_roles,
         )
 
+        bot.instance.register_command_error_manager(bootstrap_command_error_manager(bot.instance))
+
         async with bot.instance as _bot:
             _bot.add_check(whitelist_check(
                 channels=constants.WHITELISTED_CHANNELS,
diff --git a/bot/command_error_handlers/__init__.py b/bot/command_error_handlers/__init__.py
new file mode 100644
index 0000000000..a940638007
--- /dev/null
+++ b/bot/command_error_handlers/__init__.py
@@ -0,0 +1,30 @@
+from pydis_core.utils.error_handling.commands import CommandErrorManager
+
+from bot.bot import Bot
+
+from .api_error import APIErrorHandler
+from .bad_argument import BadArgumentErrorHandler
+from .check_failure import CheckFailureErrorHandler
+from .command_not_found import CommandNotFoundErrorHandler
+from .command_on_cooldown import CommandOnCooldownErrorHandler
+from .default import DefaultCommandErrorHandler
+from .disabled_command import DisabledCommandErrorHandler
+from .moved_command import MovedCommandErrorHandler
+from .user_input_error import UserInputErrorHandler
+from .user_not_playing import UserNotPlayingErrorHandler
+
+
+def bootstrap_command_error_manager(bot: Bot) -> CommandErrorManager:
+    """Bootstraps the command error manager with all the needed error handlers."""
+    default_handler = DefaultCommandErrorHandler()
+    manager = CommandErrorManager(default=default_handler)
+    manager.register_handler(CommandNotFoundErrorHandler(bot))
+    manager.register_handler(MovedCommandErrorHandler())
+    manager.register_handler(UserInputErrorHandler())
+    manager.register_handler(APIErrorHandler())
+    manager.register_handler(CommandOnCooldownErrorHandler())
+    manager.register_handler(UserNotPlayingErrorHandler())
+    manager.register_handler(BadArgumentErrorHandler())
+    manager.register_handler(CheckFailureErrorHandler())
+    manager.register_handler(DisabledCommandErrorHandler())
+    return manager
diff --git a/bot/command_error_handlers/_utils.py b/bot/command_error_handlers/_utils.py
new file mode 100644
index 0000000000..410a8b9ded
--- /dev/null
+++ b/bot/command_error_handlers/_utils.py
@@ -0,0 +1,40 @@
+import random
+from collections.abc import Iterable
+
+from discord import Embed, Message
+from discord.ext import commands
+from pydis_core.utils.logging import get_logger
+
+from bot.constants import Colours, ERROR_REPLIES
+
+log = get_logger(__name__)
+
+
+def create_error_embed(message: str, title: Iterable | str = ERROR_REPLIES) -> Embed:
+    """Build a basic embed with red colour and either a random error title or a title provided."""
+    embed = Embed(colour=Colours.soft_red)
+    if isinstance(title, str):
+        embed.title = title
+    else:
+        embed.title = random.choice(title)
+    embed.description = message
+    return embed
+
+
+def revert_cooldown_counter(command: commands.Command, message: Message) -> None:
+    """Undoes the last cooldown counter for user-error cases."""
+    if command._buckets.valid:
+        bucket = command._buckets.get_bucket(message)
+        bucket._tokens = min(bucket.rate, bucket._tokens + 1)
+        log.debug("Cooldown counter reverted as the command was not used correctly.")
+
+
+def get_parent_command_and_subcontext(context: commands.Context) -> tuple[str, commands.Context]:
+    """Extracts the parent command and subcontext, if any."""
+    parent_command = ""
+    ctx = context
+    if sub_context := getattr(context, "subcontext", None):
+        parent_command = f"{context.command} "
+        ctx = sub_context
+
+    return parent_command, ctx
diff --git a/bot/command_error_handlers/api_error.py b/bot/command_error_handlers/api_error.py
new file mode 100644
index 0000000000..3c131896d7
--- /dev/null
+++ b/bot/command_error_handlers/api_error.py
@@ -0,0 +1,36 @@
+from typing import NoReturn
+
+from discord import Interaction
+from discord.ext.commands import Context
+from pydis_core.utils.error_handling.commands import AbstractCommandErrorHandler
+
+from bot.constants import NEGATIVE_REPLIES
+from bot.utils.exceptions import APIError
+
+from ._utils import create_error_embed
+
+
+class APIErrorHandler(AbstractCommandErrorHandler):
+    """An handler for the APIError error."""
+
+    async def should_handle_error(self, error: Exception) -> bool:
+        """A predicate that determines whether the error should be handled or not."""
+        return isinstance(error, APIError)
+
+    async def handle_text_command_error(self, context: Context, error: Exception) -> NoReturn:
+        """Handle error raised in the context of text commands."""
+        await context.send(
+            embed=create_error_embed(
+                f"There was an error when communicating with the {error.api}",
+                NEGATIVE_REPLIES
+            )
+        )
+
+    async def handle_app_command_error(self, interaction: Interaction, error: Exception) -> NoReturn:
+        """Handle error raised in the context of app commands."""
+        await interaction.response.send_message(
+            embed=create_error_embed(
+                f"There was an error when communicating with the {error.api}",
+                NEGATIVE_REPLIES
+            )
+        )
diff --git a/bot/command_error_handlers/bad_argument.py b/bot/command_error_handlers/bad_argument.py
new file mode 100644
index 0000000000..1d5bb29ba3
--- /dev/null
+++ b/bot/command_error_handlers/bad_argument.py
@@ -0,0 +1,29 @@
+from typing import NoReturn
+
+from discord import Interaction
+from discord.ext.commands import BadArgument, Context
+from pydis_core.utils.error_handling.commands import AbstractCommandErrorHandler
+
+from ._utils import create_error_embed, get_parent_command_and_subcontext, revert_cooldown_counter
+
+
+class BadArgumentErrorHandler(AbstractCommandErrorHandler):
+    """An handler for the BadArgument error."""
+
+    async def should_handle_error(self, error: Exception) -> bool:
+        """A predicate that determines whether the error should be handled or not."""
+        return isinstance(error, BadArgument)
+
+    async def handle_text_command_error(self, context: Context, error: Exception) -> NoReturn:
+        """Handle error raised in the context of text commands."""
+        revert_cooldown_counter(context.command, context.message)
+        parent_command, ctx = get_parent_command_and_subcontext(context)
+        embed = create_error_embed(
+            "The argument you provided was invalid: "
+            f"{error}\n\nUsage:\n```\n{ctx.prefix}{parent_command}{ctx.command} {ctx.command.signature}\n```"
+        )
+        await context.send(embed=embed)
+
+    async def handle_app_command_error(self, interaction: Interaction, error: Exception) -> NoReturn:
+        """Handle error raised in the context of app commands."""
+        return
diff --git a/bot/command_error_handlers/check_failure.py b/bot/command_error_handlers/check_failure.py
new file mode 100644
index 0000000000..0ab6c83f7f
--- /dev/null
+++ b/bot/command_error_handlers/check_failure.py
@@ -0,0 +1,40 @@
+from typing import NoReturn
+
+from discord import Embed, Interaction
+from discord.ext.commands import CheckFailure, Context, NoPrivateMessage
+from pydis_core.utils.error_handling.commands import AbstractCommandErrorHandler
+
+from bot.constants import Channels, NEGATIVE_REPLIES
+from bot.utils.decorators import InChannelCheckFailure, InMonthCheckFailure
+
+from ._utils import create_error_embed
+
+
+class CheckFailureErrorHandler(AbstractCommandErrorHandler):
+    """An handler for the CheckFailure error."""
+
+    async def should_handle_error(self, error: Exception) -> bool:
+        """A predicate that determines whether the error should be handled or not."""
+        return isinstance(error, CheckFailure)
+
+    async def handle_text_command_error(self, context: Context, error: Exception) -> NoReturn:
+        """Handle error raised in the context of text commands."""
+        error_embed = self._get_error_embed(error)
+        await context.send(embed=error_embed, delete_after=7.5)
+        return
+
+    async def handle_app_command_error(self, interaction: Interaction, error: Exception) -> NoReturn:
+        """Handle error raised in the context of app commands."""
+        await interaction.response.send_message(embed=self._get_error_embed(error))
+
+    @staticmethod
+    def _get_error_embed(error: Exception) -> Embed:
+        if isinstance(error, InChannelCheckFailure | InMonthCheckFailure):
+            return create_error_embed(str(error), NEGATIVE_REPLIES)
+        if isinstance(error, NoPrivateMessage):
+            return create_error_embed(
+                "This command can only be used in the server. "
+                f"Go to <#{Channels.sir_lancebot_playground}> instead!",
+                NEGATIVE_REPLIES
+            )
+        return create_error_embed("You are not authorized to use this command.", NEGATIVE_REPLIES)
diff --git a/bot/command_error_handlers/command_not_found.py b/bot/command_error_handlers/command_not_found.py
new file mode 100644
index 0000000000..957b4d381c
--- /dev/null
+++ b/bot/command_error_handlers/command_not_found.py
@@ -0,0 +1,64 @@
+from typing import NoReturn
+
+from discord import Embed, Interaction, errors
+from discord.ext import commands
+from pydis_core.utils.error_handling.commands import AbstractCommandErrorHandler
+from pydis_core.utils.logging import get_logger
+
+from bot.bot import Bot
+from bot.utils.commands import get_command_suggestions
+
+log = get_logger(__name__)
+
+DELETE_DELAY = 10
+QUESTION_MARK_ICON = "https://cdn.discordapp.com/emojis/512367613339369475.png"
+
+
+class CommandNotFoundErrorHandler(AbstractCommandErrorHandler):
+    """A handler for all CommandNotFound exceptions."""
+
+    def __init__(self, bot: Bot):
+        self.bot = bot
+
+    async def should_handle_error(self, error: errors.DiscordException) -> bool:
+        """A predicate that determines whether the error should be handled or not."""
+        return isinstance(error, commands.CommandNotFound)
+
+    async def handle_app_command_error(self, interaction: Interaction, error: errors.DiscordException) -> NoReturn:
+        """Handle error raised in the context of app commands."""
+        # CommandNotFound cannot happen with app commands, so there's nothing to do here
+        return
+
+    async def handle_text_command_error(self, context: commands.Context, error: errors.DiscordException) -> NoReturn:
+        """Handle error raised in the context of text commands."""
+        if not context.invoked_with.startswith("."):
+            await self.send_command_suggestion(context, context.invoked_with)
+
+    async def send_command_suggestion(self, ctx: commands.Context, command_name: str) -> None:
+        """Sends user similar commands if any can be found."""
+        command_suggestions = []
+        if similar_command_names := get_command_suggestions(list(self.bot.all_commands.keys()), command_name):
+            for similar_command_name in similar_command_names:
+                similar_command = self.bot.get_command(similar_command_name)
+
+                if not similar_command:
+                    continue
+
+                log_msg = "Cancelling attempt to suggest a command due to failed checks."
+                try:
+                    if not await similar_command.can_run(ctx):
+                        log.debug(log_msg)
+                        continue
+                except commands.errors.CommandError:
+                    log.debug(log_msg)
+                    continue
+
+                command_suggestions.append(similar_command_name)
+
+            misspelled_content = ctx.message.content
+            e = Embed()
+            e.set_author(name="Did you mean:", icon_url=QUESTION_MARK_ICON)
+            e.description = "\n".join(
+                misspelled_content.replace(command_name, cmd, 1) for cmd in command_suggestions
+            )
+            await ctx.send(embed=e, delete_after=DELETE_DELAY)
diff --git a/bot/command_error_handlers/command_on_cooldown.py b/bot/command_error_handlers/command_on_cooldown.py
new file mode 100644
index 0000000000..37b6b30245
--- /dev/null
+++ b/bot/command_error_handlers/command_on_cooldown.py
@@ -0,0 +1,31 @@
+import math
+from typing import NoReturn
+
+from discord import Interaction
+from discord.ext.commands import CommandOnCooldown, Context
+from pydis_core.utils.error_handling.commands import AbstractCommandErrorHandler
+
+from bot.constants import NEGATIVE_REPLIES
+
+from ._utils import create_error_embed
+
+
+class CommandOnCooldownErrorHandler(AbstractCommandErrorHandler):
+    """An handler for the CommandOnCooldown error."""
+
+    async def should_handle_error(self, error: Exception) -> bool:
+        """A predicate that determines whether the error should be handled or not."""
+        return isinstance(error, CommandOnCooldown)
+
+    async def handle_text_command_error(self, context: Context, error: Exception) -> NoReturn:
+        """Handle error raised in the context of text commands."""
+        mins, secs = divmod(math.ceil(error.retry_after), 60)
+        embed = create_error_embed(
+            f"This command is on cooldown:\nPlease retry in {mins} minutes {secs} seconds.",
+            NEGATIVE_REPLIES
+        )
+        await context.send(embed=embed, delete_after=7.5)
+
+    async def handle_app_command_error(self, interaction: Interaction, error: Exception) -> NoReturn:
+        """Handle error raised in the context of app commands."""
+        raise Exception from error
diff --git a/bot/command_error_handlers/default.py b/bot/command_error_handlers/default.py
new file mode 100644
index 0000000000..324b1dfc44
--- /dev/null
+++ b/bot/command_error_handlers/default.py
@@ -0,0 +1,74 @@
+from typing import NoReturn
+
+from discord import Guild, Interaction, errors
+from discord.ext.commands import Context
+from pydis_core.utils.error_handling.commands import AbstractCommandErrorHandler
+from pydis_core.utils.logging import get_logger
+from sentry_sdk import push_scope
+
+log = get_logger(__name__)
+
+
+class DefaultCommandErrorHandler(AbstractCommandErrorHandler):
+    """A default command error handler."""
+
+    async def should_handle_error(self, error: errors.DiscordException) -> bool:
+        """A predicate that determines whether the error should be handled or not."""
+        return True
+
+    async def handle_text_command_error(self, context: Context, error: errors.DiscordException) -> NoReturn:
+        """Handle error raised in the context of text commands."""
+        self._handle_unexpected_error(
+            error=error,
+            author_id=context.author.id,
+            username=str(context.author),
+            command_name=context.command.qualified_name,
+            message_id=context.message.id,
+            channel_id=context.channel.id,
+            content=context.message.content,
+            guild=context.guild,
+            jump_url=context.message.jump_url
+        )
+
+    async def handle_app_command_error(self, interaction: Interaction, error: errors.DiscordException) -> NoReturn:
+        """Handle error raised in the context of app commands."""
+        self._handle_unexpected_error(
+            error=error,
+            author_id=interaction.user.id,
+            username=str(interaction.user),
+            command_name=interaction.command.name,
+            message_id=interaction.message.id,
+            channel_id=interaction.channel_id,
+            content=interaction.message.content,
+            guild=interaction.guild,
+            jump_url=interaction.message.jump_url
+        )
+
+    def _handle_unexpected_error(
+        self,
+        error: errors.DiscordException,
+        author_id: int,
+        username: str,
+        command_name: str,
+        message_id: int,
+        channel_id: int,
+        content: str,
+        guild: Guild | None = None,
+        jump_url: str | None = None
+    ) -> None:
+        with push_scope() as scope:
+            scope.user = {
+                "id": author_id,
+                "username": username
+            }
+
+            scope.set_tag("command", command_name)
+            scope.set_tag("message_id", message_id)
+            scope.set_tag("channel_id", channel_id)
+
+            scope.set_extra("full_message", content)
+
+            if guild is not None and jump_url is not None:
+                scope.set_extra("jump_to", jump_url)
+
+            log.exception(f"Unhandled command error: {error!s}", exc_info=error)
diff --git a/bot/command_error_handlers/disabled_command.py b/bot/command_error_handlers/disabled_command.py
new file mode 100644
index 0000000000..8b277198c7
--- /dev/null
+++ b/bot/command_error_handlers/disabled_command.py
@@ -0,0 +1,27 @@
+from typing import NoReturn
+
+from discord import Interaction
+from discord.ext.commands import Context, DisabledCommand
+from pydis_core.utils.error_handling.commands import AbstractCommandErrorHandler
+
+from bot.constants import NEGATIVE_REPLIES
+
+from ._utils import create_error_embed
+
+
+class DisabledCommandErrorHandler(AbstractCommandErrorHandler):
+    """An handler for the DisabledCommand error."""
+
+    async def should_handle_error(self, error: Exception) -> bool:
+        """A predicate that determines whether the error should be handled or not."""
+        return isinstance(error, DisabledCommand)
+
+    async def handle_text_command_error(self, context: Context, error: Exception) -> NoReturn:
+        """Handle error raised in the context of text commands."""
+        await context.send(embed=create_error_embed("This command has been disabled.", NEGATIVE_REPLIES))
+
+    async def handle_app_command_error(self, interaction: Interaction, error: Exception) -> NoReturn:
+        """Handle error raised in the context of app commands."""
+        await interaction.response.send_message(
+            embed=create_error_embed("This command has been disabled.", NEGATIVE_REPLIES)
+        )
diff --git a/bot/command_error_handlers/moved_command.py b/bot/command_error_handlers/moved_command.py
new file mode 100644
index 0000000000..d01acae429
--- /dev/null
+++ b/bot/command_error_handlers/moved_command.py
@@ -0,0 +1,40 @@
+from typing import NoReturn
+
+from discord import Embed, Interaction
+from discord.ext.commands import Context
+from pydis_core.utils.error_handling.commands import AbstractCommandErrorHandler
+
+from bot.constants import NEGATIVE_REPLIES
+from bot.utils.exceptions import MovedCommandError
+
+from ._utils import create_error_embed
+
+
+class MovedCommandErrorHandler(AbstractCommandErrorHandler):
+    """An handler for the MovedCommand error."""
+
+    async def should_handle_error(self, error: Exception) -> bool:
+        """A predicate that determines whether the error should be handled or not."""
+        return isinstance(error, MovedCommandError)
+
+    async def handle_text_command_error(self, context: Context, error: Exception) -> NoReturn:
+        """Handle error raised in the context of text commands."""
+        await context.send(
+            embed=self._get_error_embed(context.prefix, context.command.qualified_name, error.new_command_name)
+        )
+
+    async def handle_app_command_error(self, interaction: Interaction, error: Exception) -> NoReturn:
+        """Handle error raised in the context of app commands."""
+        await interaction.response.send_message(
+            embed=self._get_error_embed("/", interaction.command.name, error.new_command_name)
+        )
+
+    @staticmethod
+    def _get_error_embed(prefix: str, command_name: str, new_command_name: str) -> Embed:
+        return create_error_embed(
+            message=(
+                f"This command, `{prefix}{command_name}` has moved to `{new_command_name}`.\n"
+                f"Please use `{new_command_name}` instead."
+            ),
+            title=NEGATIVE_REPLIES
+        )
diff --git a/bot/command_error_handlers/user_input_error.py b/bot/command_error_handlers/user_input_error.py
new file mode 100644
index 0000000000..3491dfda7d
--- /dev/null
+++ b/bot/command_error_handlers/user_input_error.py
@@ -0,0 +1,29 @@
+from typing import NoReturn
+
+from discord import Interaction
+from discord.ext.commands import Context, UserInputError
+from pydis_core.utils.error_handling.commands import AbstractCommandErrorHandler
+
+from ._utils import create_error_embed, get_parent_command_and_subcontext, revert_cooldown_counter
+
+
+class UserInputErrorHandler(AbstractCommandErrorHandler):
+    """An handler for the UserInputError error."""
+
+    async def should_handle_error(self, error: Exception) -> bool:
+        """A predicate that determines whether the error should be handled or not."""
+        return isinstance(error, UserInputError)
+
+    async def handle_text_command_error(self, context: Context, error: Exception) -> NoReturn:
+        """Handle error raised in the context of text commands."""
+        revert_cooldown_counter(context.command, context.message)
+        parent_command, ctx = get_parent_command_and_subcontext(context)
+        usage = f"```\n{ctx.prefix}{parent_command}{ctx.command} {ctx.command.signature}\n```"
+        embed = create_error_embed(
+            f"Your input was invalid: {error}\n\nUsage:{usage}"
+        )
+        await context.send(embed=embed)
+
+    async def handle_app_command_error(self, interaction: Interaction, error: Exception) -> NoReturn:
+        """Handle error raised in the context of app commands."""
+        raise Exception from error
diff --git a/bot/command_error_handlers/user_not_playing.py b/bot/command_error_handlers/user_not_playing.py
new file mode 100644
index 0000000000..87542478ed
--- /dev/null
+++ b/bot/command_error_handlers/user_not_playing.py
@@ -0,0 +1,23 @@
+from typing import NoReturn
+
+from discord import Interaction
+from discord.ext.commands import Context
+from pydis_core.utils.error_handling.commands import AbstractCommandErrorHandler
+
+from bot.utils.exceptions import UserNotPlayingError
+
+
+class UserNotPlayingErrorHandler(AbstractCommandErrorHandler):
+    """An handler for the UserNotPlayingError error."""
+
+    async def should_handle_error(self, error: Exception) -> bool:
+        """A predicate that determines whether the error should be handled or not."""
+        return isinstance(error, UserNotPlayingError)
+
+    async def handle_text_command_error(self, context: Context, error: Exception) -> NoReturn:
+        """Handle error raised in the context of text commands."""
+        await context.send("Game not found.")
+
+    async def handle_app_command_error(self, interaction: Interaction, error: Exception) -> NoReturn:
+        """Handle error raised in the context of app commands."""
+        await interaction.response.send_message("Game not found.")
diff --git a/bot/exts/core/error_handler.py b/bot/exts/core/error_handler.py
index cf116ba029..cf7959e6d6 100644
--- a/bot/exts/core/error_handler.py
+++ b/bot/exts/core/error_handler.py
@@ -1,50 +1,17 @@
-import math
-import random
-from collections.abc import Iterable
-
-from discord import Embed, Message
 from discord.ext import commands
 from pydis_core.utils.logging import get_logger
-from sentry_sdk import push_scope
 
 from bot.bot import Bot
-from bot.constants import Channels, Colours, ERROR_REPLIES, NEGATIVE_REPLIES
-from bot.utils.commands import get_command_suggestions
-from bot.utils.decorators import InChannelCheckFailure, InMonthCheckFailure
-from bot.utils.exceptions import APIError, MovedCommandError, UserNotPlayingError
 
 log = get_logger(__name__)
 
 
-DELETE_DELAY = 10
-QUESTION_MARK_ICON = "https://cdn.discordapp.com/emojis/512367613339369475.png"
-
-
 class CommandErrorHandler(commands.Cog):
     """A error handler for the PythonDiscord server."""
 
     def __init__(self, bot: Bot):
         self.bot = bot
 
-    @staticmethod
-    def revert_cooldown_counter(command: commands.Command, message: Message) -> None:
-        """Undoes the last cooldown counter for user-error cases."""
-        if command._buckets.valid:
-            bucket = command._buckets.get_bucket(message)
-            bucket._tokens = min(bucket.rate, bucket._tokens + 1)
-            log.debug("Cooldown counter reverted as the command was not used correctly.")
-
-    @staticmethod
-    def error_embed(message: str, title: Iterable | str = ERROR_REPLIES) -> Embed:
-        """Build a basic embed with red colour and either a random error title or a title provided."""
-        embed = Embed(colour=Colours.soft_red)
-        if isinstance(title, str):
-            embed.title = title
-        else:
-            embed.title = random.choice(title)
-        embed.description = message
-        return embed
-
     @commands.Cog.listener()
     async def on_command_error(self, ctx: commands.Context, error: commands.CommandError) -> None:
         """Activates when a command raises an error."""
@@ -52,11 +19,6 @@ async def on_command_error(self, ctx: commands.Context, error: commands.CommandE
             log.debug(f"Command {ctx.command} had its error already handled locally; ignoring.")
             return
 
-        parent_command = ""
-        if subctx := getattr(ctx, "subcontext", None):
-            parent_command = f"{ctx.command} "
-            ctx = subctx
-
         error = getattr(error, "original", error)
         log.debug(
             f"Error Encountered: {type(error).__name__} - {error!s}, "
@@ -65,127 +27,7 @@ async def on_command_error(self, ctx: commands.Context, error: commands.CommandE
             f"Channel: {ctx.channel}"
         )
 
-        if isinstance(error, commands.CommandNotFound):
-            # Ignore messages that start with "..", as they were likely not meant to be commands
-            if not ctx.invoked_with.startswith("."):
-                await self.send_command_suggestion(ctx, ctx.invoked_with)
-            return
-
-        if isinstance(error, InChannelCheckFailure | InMonthCheckFailure):
-            await ctx.send(embed=self.error_embed(str(error), NEGATIVE_REPLIES), delete_after=7.5)
-            return
-
-        if isinstance(error, commands.UserInputError):
-            self.revert_cooldown_counter(ctx.command, ctx.message)
-            usage = f"```\n{ctx.prefix}{parent_command}{ctx.command} {ctx.command.signature}\n```"
-            embed = self.error_embed(
-                f"Your input was invalid: {error}\n\nUsage:{usage}"
-            )
-            await ctx.send(embed=embed)
-            return
-
-        if isinstance(error, commands.CommandOnCooldown):
-            mins, secs = divmod(math.ceil(error.retry_after), 60)
-            embed = self.error_embed(
-                f"This command is on cooldown:\nPlease retry in {mins} minutes {secs} seconds.",
-                NEGATIVE_REPLIES
-            )
-            await ctx.send(embed=embed, delete_after=7.5)
-            return
-
-        if isinstance(error, commands.DisabledCommand):
-            await ctx.send(embed=self.error_embed("This command has been disabled.", NEGATIVE_REPLIES))
-            return
-
-        if isinstance(error, commands.NoPrivateMessage):
-            await ctx.send(
-                embed=self.error_embed(
-                    "This command can only be used in the server. "
-                    f"Go to <#{Channels.sir_lancebot_playground}> instead!",
-                    NEGATIVE_REPLIES
-                )
-            )
-            return
-
-        if isinstance(error, commands.BadArgument):
-            self.revert_cooldown_counter(ctx.command, ctx.message)
-            embed = self.error_embed(
-                "The argument you provided was invalid: "
-                f"{error}\n\nUsage:\n```\n{ctx.prefix}{parent_command}{ctx.command} {ctx.command.signature}\n```"
-            )
-            await ctx.send(embed=embed)
-            return
-
-        if isinstance(error, commands.CheckFailure):
-            await ctx.send(embed=self.error_embed("You are not authorized to use this command.", NEGATIVE_REPLIES))
-            return
-
-        if isinstance(error, UserNotPlayingError):
-            await ctx.send("Game not found.")
-            return
-
-        if isinstance(error, APIError):
-            await ctx.send(
-                embed=self.error_embed(
-                    f"There was an error when communicating with the {error.api}",
-                    NEGATIVE_REPLIES
-                )
-            )
-            return
-
-        if isinstance(error, MovedCommandError):
-            description = (
-                f"This command, `{ctx.prefix}{ctx.command.qualified_name}` has moved to `{error.new_command_name}`.\n"
-                f"Please use `{error.new_command_name}` instead."
-            )
-            await ctx.send(embed=self.error_embed(description, NEGATIVE_REPLIES))
-            return
-
-        with push_scope() as scope:
-            scope.user = {
-                "id": ctx.author.id,
-                "username": str(ctx.author)
-            }
-
-            scope.set_tag("command", ctx.command.qualified_name)
-            scope.set_tag("message_id", ctx.message.id)
-            scope.set_tag("channel_id", ctx.channel.id)
-
-            scope.set_extra("full_message", ctx.message.content)
-
-            if ctx.guild is not None:
-                scope.set_extra("jump_to", ctx.message.jump_url)
-
-            log.exception(f"Unhandled command error: {error!s}", exc_info=error)
-
-    async def send_command_suggestion(self, ctx: commands.Context, command_name: str) -> None:
-        """Sends user similar commands if any can be found."""
-        command_suggestions = []
-        if similar_command_names := get_command_suggestions(list(self.bot.all_commands.keys()), command_name):
-            for similar_command_name in similar_command_names:
-                similar_command = self.bot.get_command(similar_command_name)
-
-                if not similar_command:
-                    continue
-
-                log_msg = "Cancelling attempt to suggest a command due to failed checks."
-                try:
-                    if not await similar_command.can_run(ctx):
-                        log.debug(log_msg)
-                        continue
-                except commands.errors.CommandError:
-                    log.debug(log_msg)
-                    continue
-
-                command_suggestions.append(similar_command_name)
-
-            misspelled_content = ctx.message.content
-            e = Embed()
-            e.set_author(name="Did you mean:", icon_url=QUESTION_MARK_ICON)
-            e.description = "\n".join(
-                misspelled_content.replace(command_name, cmd, 1) for cmd in command_suggestions
-            )
-            await ctx.send(embed=e, delete_after=DELETE_DELAY)
+        await self.bot.command_error_manager.handle_error(error, ctx)
 
 
 async def setup(bot: Bot) -> None:
diff --git a/poetry.lock b/poetry.lock
index 9aa68fd1de..4d63b6f95e 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1250,13 +1250,13 @@ yaml = ["pyyaml (>=6.0.1)"]
 
 [[package]]
 name = "pydis-core"
-version = "11.0.0"
+version = "11.0.1"
 description = "PyDis core provides core functionality and utility to the bots of the Python Discord community."
 optional = false
-python-versions = ">=3.11.dev0,<3.13.dev0"
+python-versions = "<3.13.dev0,>=3.11.dev0"
 files = [
-    {file = "pydis_core-11.0.0-py3-none-any.whl", hash = "sha256:912962fe0417a0d8d68835d0b4646b2c04c0ec674aed5bb158db3d6f6f9571e1"},
-    {file = "pydis_core-11.0.0.tar.gz", hash = "sha256:f294ddf0d05dd30b7a4a039e95ff217fcc23f7239c415582fdff3b51b5d9c682"},
+    {file = "pydis_core-11.0.1-py3-none-any.whl", hash = "sha256:bcf3c81f510c6d19013b650a8bae28f95519d465bf6d4b798bf1ce8fc5e96cf5"},
+    {file = "pydis_core-11.0.1.tar.gz", hash = "sha256:785193ab6ef67c64587dc68c6d8f61206a5a02e067d4dd9c6676ba88cdbe61a7"},
 ]
 
 [package.dependencies]
@@ -1841,4 +1841,4 @@ multidict = ">=4.0"
 [metadata]
 lock-version = "2.0"
 python-versions = "3.11.*"
-content-hash = "576dc922030d79dab60f47bf0f7a51b2f9d36679ac06c64f1204bfa1ddb08bd5"
+content-hash = "faa60f7b8cdaf838cabe5efa240d0fd9a38efaa19bc9dccd5338ab116295b50d"
diff --git a/pyproject.toml b/pyproject.toml
index c4a4deb69e..42a1ef2ed7 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -9,7 +9,7 @@ license = "MIT"
 python = "3.11.*"
 
 # See https://bot-core.pythondiscord.com/ for docs.
-pydis_core = { version = "11.0.0", extras = ["all"] }
+pydis_core = { version = "11.0.1", extras = ["all"] }
 
 rapidfuzz = "3.6.2"
 arrow = "1.3.0"