Skip to content
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

Use botcore command error manager #1458

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

shtlrs
Copy link
Member

@shtlrs shtlrs commented Feb 18, 2024

This deflates the CommandErrorHandler from all the conditionals in place when it comes to error types.
Most importantly, it allows us to centralize error handling of both text and slash commands in one place, and reuse any necessary logic.

@shtlrs shtlrs force-pushed the use-botcore-command-error-manager branch 2 times, most recently from fd6490c to 9d330d0 Compare March 18, 2024 12:58
@shtlrs shtlrs requested review from MarkKoz and Xithrius March 18, 2024 12:58
@shtlrs shtlrs force-pushed the use-botcore-command-error-manager branch from 9d330d0 to 832acb1 Compare March 20, 2024 18:15
@shtlrs
Copy link
Member Author

shtlrs commented Mar 20, 2024

I'll squash the implementation commits along with the fixup one once the PR is ready to be merged.

@shtlrs shtlrs force-pushed the use-botcore-command-error-manager branch from 832acb1 to 5c610e0 Compare March 20, 2024 23:00
@shtlrs shtlrs force-pushed the use-botcore-command-error-manager branch from 5c610e0 to 6f8a5b1 Compare March 21, 2024 13:29
@wookie184
Copy link
Contributor

Honestly, I don't understand the benefit of this error dispatching system. I feel like this introduces extra complexity and makes the logic much harder to follow and understand.

Before, following the logic was as simple as:

  1. on_command_error is called
  2. isinstance is used to dispatch the error to the necessary handling logic

Now, to follow the logic it's:

  1. on_command_error is called

  2. It gets self.bot.command_error_manager

    • ...which is set by register_command_error_manager in bot-core
    • ...which is called by the return value of bootstrap_command_error_manager in bot/__main__.py
    • ...which is defined in bot/command_error_handlers/__init__.py, and constructs the CommandErrorManager
  3. It calls handle_error on self.bot.command_error_manager.

    • This runs through self._handlers (which was set by calls to register_handler back in bot/command_error_handlers/__init__.py) and calls should_handle_error on each handler
    • This actual should_handle_error function is split over a lot of files.
    • isinstance is used to determine whether the function should be run.
    • _get_callback is called and the correct function is selected
    • The function is called.

I'm not sure what benefit these extra steps have given us over the current code.

@shtlrs
Copy link
Member Author

shtlrs commented Mar 26, 2024

The idea initially came to make the exception handling logic reusable for both prefix command & slash command errors.

For context, we have some prefix/text commands that also have their slash version sibling, and these commands use the same logic/throw the same errors.

The question was (and I'd be interested to have your point of view), how do we reuse all the logic that existed in the error handling cog in case we have errors that came from these slash commands ?

Discord py dispatches these prefix commands through the on_command_error callback, and the ones coming from slash commands through the CommandTree's on_error callback, which both have different signatures since one relies on Context and the other relies on Interaction. So trying to relay errors from the on_error to the on_command_error one needs some sort of conversion.

I just thought of unifying both under the same interface and hiding the conversion details for the same type of error.

I understand your point of view and agree that it's slightly more complex than the setup we currently have but I don't necessarily agree that it's makes it much harder to follow nor that complex, but that could just be the fact that I'm biased since I'm the one who wrote, which makes the understanding easier.

Copy link
Member

@MarkKoz MarkKoz left a comment

Choose a reason for hiding this comment

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

A few preliminary comments - still need to do a deeper review.

"""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:
Copy link
Member

Choose a reason for hiding this comment

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

The default value of a function is None. If a function can return, but has no explicit return value, then this annotation should be None.

NoReturn means it does not return i.e. control flow of the program is interrupted before it returns. I've only seen this used for functions that always throw an exception, like an abstract method that raises NotImplemented. Also, this was superceded (?) in 3.11 by Never.

def __init__(self, bot: Bot):
self.bot = bot

async def should_handle_error(self, error: errors.DiscordException) -> bool:
Copy link
Member

Choose a reason for hiding this comment

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

Thoughts about using @typing.override for these? It makes it more explicit that this is an override, and it helps type checkers. But if we don't use a type checker then it could be argued that this would just clutter the code.

@Xithrius Xithrius removed their request for review May 13, 2024 00:33
@Xithrius Xithrius added area: backend Related to internal functionality and utilities status: waiting for author Waiting for author to address a review or respond to a comment type: enhancement Changes or improvements to existing features category: core Related to core functionality labels May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: backend Related to internal functionality and utilities category: core Related to core functionality status: waiting for author Waiting for author to address a review or respond to a comment type: enhancement Changes or improvements to existing features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants