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

Improve error handling #130

Merged
merged 7 commits into from
Jun 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion bot/cogs/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from libs.tickets.utils import get_cached_thread
from libs.utils import GuildContext
from libs.utils.checks import bot_check_permissions, check_permissions
from libs.utils.embeds import Embed
from libs.utils.embeds import CooldownEmbed, Embed
from libs.utils.pages import SimplePages
from libs.utils.prefix import get_prefix

Expand Down Expand Up @@ -242,6 +242,14 @@ async def get_block_ticket(

return BlocklistTicket(cog=tickets_cog, thread=cached_ticket.thread)

### Misc Utilities
async def _handle_error(
self, ctx: GuildContext, error: commands.CommandError
) -> None:
if isinstance(error, commands.CommandOnCooldown):
embed = CooldownEmbed(error.retry_after)
await ctx.send(embed=embed)

@check_permissions(manage_guild=True)
@bot_check_permissions(manage_channels=True, manage_webhooks=True)
@commands.guild_only()
Expand Down Expand Up @@ -463,6 +471,18 @@ async def delete(self, ctx: GuildContext) -> None:
else:
await ctx.send("Cancelling.")

@setup.error
async def on_setup_error(
self, ctx: GuildContext, error: commands.CommandError
) -> None:
await self._handle_error(ctx, error)

@delete.error
async def on_delete_error(
self, ctx: GuildContext, error: commands.CommandError
) -> None:
await self._handle_error(ctx, error)

@check_permissions(manage_guild=True)
@commands.guild_only()
@config.group(name="prefix", fallback="info")
Expand Down
10 changes: 9 additions & 1 deletion bot/cogs/tickets.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
safe_content,
)
from libs.utils.checks import bot_check_permissions
from libs.utils.embeds import Embed, LoggingEmbed
from libs.utils.embeds import CooldownEmbed, Embed, LoggingEmbed

from .config import GuildWebhookDispatcher

Expand Down Expand Up @@ -526,6 +526,14 @@ async def on_ticket_close(
embed.add_field(name="Link", value=ticket.mention)
await webhook.send(embed=embed)

@reply.error
async def on_reply_error(
self, ctx: GuildContext, error: commands.CommandError
) -> None:
if isinstance(error, commands.CommandOnCooldown):
embed = CooldownEmbed(error.retry_after)
await ctx.send(embed=embed)


async def setup(bot: Rodhaj) -> None:
await bot.add_cog(Tickets(bot))
1 change: 0 additions & 1 deletion bot/libs/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
ErrorEmbed as ErrorEmbed,
LoggingEmbed as LoggingEmbed,
)
from .errors import send_error_embed as send_error_embed
from .handler import KeyboardInterruptHandler as KeyboardInterruptHandler
from .help import RodhajHelp as RodhajHelp
from .logger import RodhajLogger as RodhajLogger
Expand Down
30 changes: 30 additions & 0 deletions bot/libs/utils/embeds.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import traceback

import discord


Expand All @@ -23,3 +25,31 @@ def __init__(self, **kwargs):
"Uh oh! It seems like the command ran into an issue! For support, ask the dev team",
)
super().__init__(**kwargs)


class FullErrorEmbed(ErrorEmbed):
def __init__(self, error: Exception, **kwargs):
kwargs.setdefault("description", self._format_description(error))
super().__init__(**kwargs)

def _format_description(self, error: Exception) -> str:
error_traceback = "\n".join(traceback.format_exception_only(type(error), error))
desc = f"""
Uh oh! It seems like there was an issue. Ask the devs for help.

**Error**:
```{error_traceback}```
"""
return desc


class CooldownEmbed(discord.Embed):
def __init__(self, retry_after: float, **kwargs):
kwargs.setdefault("color", discord.Color.from_rgb(214, 6, 6))
kwargs.setdefault("timestamp", discord.utils.utcnow())
kwargs.setdefault("title", "Command On Cooldown")
kwargs.setdefault(
"description",
f"This command is on cooldown. Try again in {retry_after:.2f}s",
)
super().__init__(**kwargs)
61 changes: 0 additions & 61 deletions bot/libs/utils/errors.py

This file was deleted.

4 changes: 2 additions & 2 deletions bot/libs/utils/modals.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import discord

from .context import RoboContext
from .errors import produce_error_embed
from .embeds import FullErrorEmbed

NO_CONTROL_MSG = "This modal cannot be controlled by you, sorry!"

Expand All @@ -28,6 +28,6 @@ async def on_error(
self, interaction: discord.Interaction, error: Exception, /
) -> None:
await interaction.response.send_message(
embed=produce_error_embed(error), ephemeral=True
embed=FullErrorEmbed(error), ephemeral=True
)
self.stop()
4 changes: 2 additions & 2 deletions bot/libs/utils/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import discord
from discord import app_commands

from .errors import produce_error_embed
from .embeds import FullErrorEmbed

if TYPE_CHECKING:
from rodhaj import Rodhaj
Expand All @@ -25,4 +25,4 @@ async def interaction_check(self, interaction: discord.Interaction, /) -> bool:
async def on_error(
self, interaction: discord.Interaction, error: app_commands.AppCommandError
) -> None:
await interaction.response.send_message(embed=produce_error_embed(error))
await interaction.response.send_message(embed=FullErrorEmbed(error))
5 changes: 2 additions & 3 deletions bot/libs/utils/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

import discord

from .embeds import ErrorEmbed
from .errors import produce_error_embed
from .embeds import ErrorEmbed, FullErrorEmbed

if TYPE_CHECKING:
from .context import RoboContext
Expand Down Expand Up @@ -38,7 +37,7 @@ async def on_error(
/,
) -> None:
await interaction.response.send_message(
embed=produce_error_embed(error), ephemeral=True
embed=FullErrorEmbed(error), ephemeral=True
)
self.stop()

Expand Down
27 changes: 19 additions & 8 deletions bot/rodhaj.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,14 @@
from libs.tickets.structs import PartialConfig, ReservedTags, StatusChecklist
from libs.tickets.utils import get_cached_thread, get_partial_ticket
from libs.tickets.views import TicketConfirmView
from libs.utils import (
RoboContext,
RodhajCommandTree,
RodhajHelp,
send_error_embed,
)
from libs.utils import RoboContext, RodhajCommandTree, RodhajHelp
from libs.utils.config import RodhajConfig
from libs.utils.prefix import get_prefix
from libs.utils.reloader import Reloader

if TYPE_CHECKING:
from cogs.tickets import Tickets
from libs.utils.context import RoboContext


class Rodhaj(commands.Bot):
Expand Down Expand Up @@ -89,9 +85,24 @@ async def get_context(
return await super().get_context(origin, cls=cls)

async def on_command_error(
self, ctx: commands.Context, error: commands.CommandError
self, ctx: RoboContext, error: commands.CommandError
) -> None:
await send_error_embed(ctx, error)
if self._dev_mode:
self.logger.exception("Ignoring exception:", exc_info=error)
return

if isinstance(error, commands.NoPrivateMessage):
await ctx.author.send("This command cannot be used in private messages")
elif isinstance(error, commands.MissingRequiredArgument):
await ctx.send(
f"You are missing the following argument(s): {error.param.name}"
)
elif isinstance(error, commands.CommandInvokeError):
original = error.original
if not isinstance(original, discord.HTTPException):
self.logger.exception("In %s:", ctx.command.qualified_name, exc_info=original) # type: ignore
elif isinstance(error, commands.BadArgument):
await ctx.send(str(error))

### Ticket processing and handling

Expand Down
Loading