Skip to content

Commit

Permalink
Merge 09472f3 into 0c4e1c2
Browse files Browse the repository at this point in the history
  • Loading branch information
onerandomusername authored Apr 21, 2022
2 parents 0c4e1c2 + 09472f3 commit d57e899
Show file tree
Hide file tree
Showing 2 changed files with 441 additions and 109 deletions.
80 changes: 45 additions & 35 deletions modmail/extensions/utils/error_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

ANY_DEV_MODE = BOT_MODE & (BotModes.DEVELOP.value + BotModes.PLUGIN_DEV.value)

MAYBE_DM_ON_PERM_ERROR = True


class ErrorHandler(ModmailCog, name="Error Handler"):
"""Handles all errors across the bot."""
Expand All @@ -43,7 +45,7 @@ def get_title_from_name(error: typing.Union[Exception, str]) -> str:
Eg NSFWChannelRequired returns NSFW Channel Required
"""
if not isinstance(error, str):
error = error.__class__.__name__
error = type(error).__name__
return re.sub(ERROR_TITLE_REGEX, r" \1", error)

@staticmethod
Expand All @@ -70,13 +72,12 @@ async def handle_user_input_error(
async def handle_bot_missing_perms(
self, ctx: commands.Context, error: commands.BotMissingPermissions
) -> bool:
"""Handles bot missing permissing by dming the user if they have a permission which may be able to fix this.""" # noqa: E501
"""Handles bot missing permissions by dming the user if they have a permission which may be able to fix this.""" # noqa: E501
embed = self.error_embed("Permissions Failure", str(error))
bot_perms = ctx.channel.permissions_for(ctx.me)
not_responded = True
if bot_perms >= discord.Permissions(send_messages=True, embed_links=True):
await ctx.send(embeds=[embed])
not_responded = False
return True
elif bot_perms >= discord.Permissions(send_messages=True):
# make a message as similar to the embed, using as few permissions as possible
# this is the only place we send a standard message instead of an embed
Expand All @@ -85,21 +86,21 @@ async def handle_bot_missing_perms(
"**Permissions Failure**\n\n"
"I am missing the permissions required to properly execute your command."
)
# intentionally not setting responded to True, since we want to attempt to dm the user
# intentionally skipping setting responded to True, since we want to attempt to dm the user
logger.warning(
f"Missing partial required permissions for {ctx.channel}. "
"I am able to send messages, but not embeds."
)
else:
logger.error(f"Unable to send an error message to channel {ctx.channel}")

if not_responded and ANY_DEV_MODE:
if MAYBE_DM_ON_PERM_ERROR or ANY_DEV_MODE:
# non-general permissions
perms = discord.Permissions(
administrator=True,
manage_threads=True,
manage_roles=True,
manage_channels=True,
manage_roles=True,
manage_threads=True,
)
if perms.value & ctx.channel.permissions_for(ctx.author).value:
logger.info(
Expand All @@ -111,7 +112,8 @@ async def handle_bot_missing_perms(
except discord.Forbidden:
logger.notice("Also encountered an error when trying to reply in dms.")
return False
return True
else:
return True

async def handle_check_failure(
self, ctx: commands.Context, error: commands.CheckFailure
Expand All @@ -135,6 +137,38 @@ async def handle_check_failure(
embed = self.error_embed(title, str(error))
return embed

async def handle_command_invoke_error(
self, ctx: commands.Context, error: commands.CommandInvokeError
) -> typing.Optional[discord.Embed]:
"""Formulate an embed for a generic error handler."""
if isinstance(error.original, discord.Forbidden):
logger.warn(f"Permissions error occurred in {ctx.command}.")
await self.handle_bot_missing_perms(ctx, error.original)
return None

# todo: this should properly handle plugin errors and note that they are not bot bugs
# todo: this should log somewhere else since this is a bot bug.
# generic error
logger.error(f'Error occurred in command "{ctx.command}".', exc_info=error.original)
if ctx.command.cog.__module__.startswith("modmail.plugins"):
# plugin msg
title = "Plugin Internal Error Occurred"
msg = (
"Something went wrong internally in the plugin contributed command you were trying "
"to execute. Please report this error and what you were trying to do to the "
"respective plugin developers.\n\n**PLEASE NOTE**: Modmail developers will not help "
"you with this issue and will refer you to the plugin developers."
)
else:
# built in command msg
title = "Internal Error"
msg = (
"Something went wrong internally in the command you were trying to execute. "
"Please report this error and what you were trying to do to the bot developers."
)
logger.debug(ctx.command.callback.__module__)
return self.error_embed(title, msg)

@ModmailCog.listener()
async def on_command_error(self, ctx: commands.Context, error: commands.CommandError) -> None:
"""Activates when a command raises an error."""
Expand Down Expand Up @@ -174,33 +208,9 @@ async def on_command_error(self, ctx: commands.Context, error: commands.CommandE
embed = self.error_embed("Command Disabled", msg)

elif isinstance(error, commands.CommandInvokeError):
if isinstance(error.original, discord.Forbidden):
logger.warn(f"Permissions error occurred in {ctx.command}.")
await self.handle_bot_missing_perms(ctx, error.original)
embed = await self.handle_command_invoke_error(ctx, error)
if embed is None:
should_respond = False
else:
# todo: this should properly handle plugin errors and note that they are not bot bugs
# todo: this should log somewhere else since this is a bot bug.
# generic error
logger.error(f'Error occurred in command "{ctx.command}".', exc_info=error.original)
if ctx.command.cog.__module__.startswith("modmail.plugins"):
# plugin msg
title = "Plugin Internal Error Occurred"
msg = (
"Something went wrong internally in the plugin contributed command you were trying "
"to execute. Please report this error and what you were trying to do to the "
"respective plugin developers.\n\n**PLEASE NOTE**: Modmail developers will not help "
"you with this issue and will refer you to the plugin developers."
)
else:
# built in command msg
title = "Internal Error"
msg = (
"Something went wrong internally in the command you were trying to execute. "
"Please report this error and what you were trying to do to the bot developers."
)
logger.debug(ctx.command.callback.__module__)
embed = self.error_embed(title, msg)

# TODO: this has a fundamental problem with any BotMissingPermissions error
# if the issue is the bot does not have permissions to send embeds or send messages...
Expand Down
Loading

0 comments on commit d57e899

Please sign in to comment.