-
Notifications
You must be signed in to change notification settings - Fork 1
feat: ✨ Add global error handler #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I just realised the message_commands are commands for the message apps menu, not prefix commands LOL
|
Made to address #23, probably shoulda mentioned that in the original message.... |
This might take a few commits to get right, don't judge me ok.
I did say this might take a while. Still no judging allowed.
feat/error_handler from fork upstream into main| _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."), | ||
| ) |
There was a problem hiding this comment.
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
| 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 |
There was a problem hiding this comment.
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
| 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. | ||
|
|
There was a problem hiding this comment.
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.
| """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 | ||
| """ |
There was a problem hiding this comment.
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
|
Thanks for your PR though, didn't think anyone would find it / contribute this fast 😄 |
Adds the
error_handler.pycog which uses theon_application_command_errorlistener to respond to errors with an appropriate message and an error code, rather than causing a simpleThis 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).