Skip to content

Commit

Permalink
Provide sane UI defaults + error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
No767 committed Nov 3, 2023
1 parent a81762d commit 5c17f4d
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 35 deletions.
5 changes: 3 additions & 2 deletions bot/cogs/dev_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import discord
from cogs import EXTENSIONS
from discord import app_commands
from discord.ext import commands
from discord.ext.commands import Context, Greedy

Expand All @@ -19,7 +20,7 @@ def __init__(self, bot: Rodhaj):
# https://about.abstractumbra.dev/discord.py/2023/01/29/sync-command-example.html
@commands.guild_only()
@commands.is_owner()
@commands.command(name="sync", hidden=True)
@commands.command(name="sync")
async def sync(
self,
ctx: Context,
Expand Down Expand Up @@ -65,7 +66,7 @@ async def sync(

@commands.guild_only()
@commands.is_owner()
@commands.command(name="reload-all", hidden=True)
@commands.command(name="reload-all")
async def reload_all(self, ctx: commands.Context) -> None:
"""Reloads all cogs. Used in production to not produce any downtime"""
if not hasattr(self.bot, "uptime"):
Expand Down
18 changes: 9 additions & 9 deletions bot/launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
from rodhaj import Rodhaj

# Only used for Windows development
if os.name == "nt":
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
else:
try:
import uvloop

asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
except ImportError:
pass
# if os.name == "nt":
# asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
# else:
# try:
# import uvloop

# asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
# except ImportError:
# pass

load_dotenv()

Expand Down
4 changes: 2 additions & 2 deletions bot/libs/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .embeds import Embed as Embed
from .embeds import ErrorEmbed as ErrorEmbed
from .embeds import Embed as Embed, ErrorEmbed as ErrorEmbed
from .logger import RodhajLogger as RodhajLogger
from .modals import RoboModal as RoboModal
from .time import human_timedelta as human_timedelta
from .tree import RodhajCommandTree as RodhajCommandTree
from .views import RoboView as RoboView
20 changes: 20 additions & 0 deletions bot/libs/utils/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import traceback

import discord

from .embeds import ErrorEmbed


def produce_error_embed(error: Exception) -> ErrorEmbed:
error_traceback = "\n".join(traceback.format_exception_only(type(error), error))
embed = ErrorEmbed()
desc = f"""
Uh oh! It seems like there was an issue. Ask the devs for help.
**Error**:
```{error_traceback}```
"""
embed.description = desc
embed.set_footer(text="Happened At")
embed.timestamp = discord.utils.utcnow()
return embed
30 changes: 30 additions & 0 deletions bot/libs/utils/modals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import discord

from .errors import produce_error_embed

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


class RoboModal(discord.ui.Modal):
"""Subclassed `discord.ui.Modal` that includes sane default configs"""

def __init__(self, interaction: discord.Interaction, *args, **kwargs):
super().__init__(*args, **kwargs)
self.interaction = interaction

async def interaction_check(self, interaction: discord.Interaction, /) -> bool:
if interaction.user and interaction.user.id in (
self.interaction.client.application.owner.id, # type: ignore
self.interaction.user.id,
):
return True
await interaction.response.send_message(NO_CONTROL_MSG, ephemeral=True)
return False

async def on_error(
self, interaction: discord.Interaction, error: Exception, /
) -> None:
await interaction.response.send_message(
embed=produce_error_embed(error), ephemeral=True
)
self.stop()
6 changes: 4 additions & 2 deletions bot/libs/utils/pages/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from .paginator import HajPages as HajPages
from .simple_pages import SimplePages as SimplePages
from .sources import EmbedListSource as EmbedListSource
from .sources import SimplePageSource as SimplePageSource
from .sources import (
EmbedListSource as EmbedListSource,
SimplePageSource as SimplePageSource,
)
22 changes: 4 additions & 18 deletions bot/libs/utils/tree.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,14 @@
import traceback

import discord
from discord import app_commands
from discord.utils import utcnow
from libs.utils import ErrorEmbed

from .errors import produce_error_embed

class RodhajCommandTree(app_commands.CommandTree):
def build_error_embed(self, error: app_commands.AppCommandError) -> ErrorEmbed:
error_traceback = "\n".join(traceback.format_exception_only(type(error), error))
embed = ErrorEmbed()
embed.description = f"""
Uh oh! It seems like the command ran into an issue!
**Error**:
```
{error_traceback}
```
"""
embed.set_footer(text="Happened At")
embed.timestamp = utcnow()
return embed

# Later on if we needed global interaction checks, we can do it here
class RodhajCommandTree(app_commands.CommandTree):
async def on_error(
self, interaction: discord.Interaction, error: app_commands.AppCommandError
) -> None:
await interaction.response.send_message(embed=self.build_error_embed(error))
await interaction.response.send_message(embed=produce_error_embed(error))
25 changes: 23 additions & 2 deletions bot/libs/utils/views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
from typing import Any

import discord

NO_CONTROL_MSG = "This menu cannot be controlled by you, sorry!"
from .errors import produce_error_embed

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


# TODO: Include the view that Soheab created
class RoboView(discord.ui.View):
"""Subclassed `discord.ui.View` that includes sane default configs"""

def __init__(self, interaction: discord.Interaction):
super().__init__()
self.interaction = interaction
Expand All @@ -17,3 +22,19 @@ async def interaction_check(self, interaction: discord.Interaction, /) -> bool:
return True
await interaction.response.send_message(NO_CONTROL_MSG, ephemeral=True)
return False

async def on_error(
self,
interaction: discord.Interaction,
error: Exception,
item: discord.ui.Item[Any],
/,
) -> None:
await interaction.response.send_message(
embed=produce_error_embed(error), ephemeral=True
)
self.stop()

async def on_timeout(self) -> None:
if self.interaction.response.is_done():
await self.interaction.edit_original_response(view=None)
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ jishaku = "^2.5.2"

[tool.isort]
profile = 'black'
combine_as_imports = true
combine_star = true
line_length = 80

[tool.pyright]
include = ["bot/**"]
Expand Down

0 comments on commit 5c17f4d

Please sign in to comment.