Skip to content

Conversation

@tobezdev
Copy link

@tobezdev tobezdev commented Feb 9, 2026

Adds the error_handler.py cog which uses the on_application_command_error listener to respond to errors with an appropriate message and an error code, rather than causing a simple This application did not respond. message or even a bot crash.

This was tested on Python 3.13.11 with py-cord v2.7.0 as outlined in pyproject.toml.
The run command used for this test was: python3 -m src -u .\src\__main__.py (executed from the project's root directory).

@tobezdev
Copy link
Author

tobezdev commented Feb 9, 2026

Made to address #23, probably shoulda mentioned that in the original message....

@ToothyDev ToothyDev linked an issue Feb 9, 2026 that may be closed by this pull request
autofix-ci bot and others added 5 commits February 9, 2026 19:44
@ToothyDev ToothyDev changed the title Merge feat/error_handler from fork upstream into main feat: ✨ Add global error handler Feb 9, 2026
Comment on lines +21 to +54
_ERROR_MESSAGES: tuple[tuple[type[BaseException], str], ...] = (
(commands.CommandNotFound, "That command doesn't exist."),
(commands.MissingRequiredArgument, "You forgot to include a required argument."),
(commands.BadArgument, "One or more arguments were invalid or in the wrong format."),
(commands.DisabledCommand, "That command is currently disabled."),
(commands.NoPrivateMessage, "This command can't be used in DMs."),
(commands.MissingPermissions, "You don't have the required permissions to use this command."),
(commands.BotMissingPermissions, "I don't have the required permissions to perform that action."),
(commands.CommandOnCooldown, "That command is on cooldown. Try again in a moment."),
(commands.MaxConcurrencyReached, "Too many people are using this command at once. Please try again later."),
(errors.ExtensionFailed, "An extension failed to load due to an internal error."),
(errors.ExtensionNotFound, "Couldn't find that extension."),
(errors.ExtensionAlreadyLoaded, "That extension is already loaded."),
(errors.ExtensionNotLoaded, "That extension isn't currently loaded."),
(commands.NotOwner, "Only the bot owner can use this command."),
(commands.CheckFailure, "You didn't pass a permission or condition check for this command."),
(commands.CommandInvokeError, "An unexpected error occurred while running that command."),
(discord.InteractionResponded, "This interaction has already been responded to."),
(
discord.ApplicationCommandInvokeError,
"Something went wrong while executing that application command.",
),
(discord.CheckFailure, "You don't meet the requirements to run this interaction."),
(discord.Forbidden, "I don't have permission to do that."),
(discord.NotFound, "That resource couldn't be found."),
(discord.DiscordServerError, "Discord's servers had an internal error."),
(discord.HTTPException, "A request to Discord's API failed unexpectedly."),
(discord.ConnectionClosed, "The connection to Discord was unexpectedly closed."),
(discord.GatewayNotFound, "Couldn't connect to Discord's gateway."),
(discord.InvalidArgument, "One or more arguments provided were invalid."),
(discord.InvalidData, "Discord returned invalid or incomplete data."),
(discord.ClientException, "The bot encountered a misuse or internal setup issue."),
(discord.LoginFailure, "The bot token provided is invalid."),
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a dict so you can use the in operator later and not need to iterate over it

Comment on lines +57 to +69
def generate_error_code(length: int = 12) -> str:
alphabet = string.ascii_uppercase + string.ascii_lowercase + string.digits
return "".join(secrets.choice(alphabet) for _ in range(length))


def get_error_message(error: Exception) -> str:
msg: str | None = None
errcode: str = generate_error_code()

for exc_type, exc_msg in _ERROR_MESSAGES:
if isinstance(error, exc_type):
msg = exc_msg
break
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generating a random error code to give to the user when we don't keep that code anywhere is pointless; Give the user a generic message that says the error has been logged instead

Comment on lines +88 to +92
print(exception)
# This maintains the default implementation of printing to sys.stderr as specified on the docs here:
# https://docs.pycord.dev/en/v2.7.0/api/clients.html#discord.Bot.on_application_command_error
# This can be removed if the user does not want to print errors and only wants to handle them in Discord.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of a print, a logger should be used, and we don't need ChatGPT comments in the code.

Comment on lines +1 to +12
"""Error handler cog.

A simple error handling cog using on_application_command_error and on_command_error events.
This handles events for both application (slash) commands and text (prefixed) commands.

All code is correct as of, and has been tested with, Python 3.13.11 with py-cord v2.7.0 as required in pyproject.toml


Cog written by tobezdev:
Github: https://github.com/tobezdev
Website: https://tobezdev.com
"""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The top part of this docstring should be on the cog class itself, not the file, and doesn't need to contain which python version it was tested on or who wrote it

@ToothyDev
Copy link
Collaborator

Thanks for your PR though, didn't think anyone would find it / contribute this fast 😄

@tobezdev tobezdev closed this by deleting the head repository Feb 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add global error handler

2 participants