-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy patherror.py
104 lines (93 loc) · 3.61 KB
/
error.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
"""
Error - Rich error handling cog
Features: determine the nature of the error and explain what went wrong
Recommended cogs: Help
"""
from __future__ import annotations
from typing import TYPE_CHECKING
import asyncio, traceback
import discord
from discord import app_commands
from discord.ext import commands
if TYPE_CHECKING:
from main import MerelyBot
from babel import Resolvable
from configparser import SectionProxy
class Error(commands.Cog):
""" Catches errors and provides users with a response """
SCOPE = 'error'
@property
def config(self) -> SectionProxy:
""" Shorthand for self.bot.config[scope] """
return self.bot.config[self.SCOPE]
def babel(self, target:Resolvable, key:str, **values: dict[str, str | bool]) -> str:
""" Shorthand for self.bot.babel(scope, key, **values) """
return self.bot.babel(target, self.SCOPE, key, **values)
def __init__(self, bot:MerelyBot):
self.bot = bot
bot.tree.error(self.handle_error)
async def handle_error(
self,
inter:discord.Interaction,
error:app_commands.AppCommandError
):
""" Report to the user what went wrong """
send = (inter.followup.send if inter.response.is_done() else inter.response.send_message)
print("error detected")
try:
if isinstance(error, app_commands.CommandOnCooldown):
if error.cooldown.get_retry_after() > 5:
await send(
self.babel(inter, 'cooldown', t=int(error.cooldown.get_retry_after())),
ephemeral=True
)
return
print("cooldown")
return
kwargs = {'ephemeral': True}
if isinstance(
error,
(app_commands.CommandNotFound, commands.BadArgument, commands.MissingRequiredArgument)
):
if 'Help' in self.bot.cogs:
await send(
await self.bot.cogs['Help'].resolve_docs(inter, inter.command.name),
**kwargs
)
else:
await send(self.babel(inter, 'missingrequiredargument'), **kwargs)
return
if isinstance(error, app_commands.NoPrivateMessage):
await send(self.babel(inter, 'noprivatemessage'), **kwargs)
return
if isinstance(error, commands.PrivateMessageOnly):
await send(self.babel(inter, 'privatemessageonly'), **kwargs)
return
if isinstance(error, (app_commands.BotMissingPermissions, app_commands.MissingPermissions)):
permlist = self.bot.babel.string_list(inter, [f'`{p}`' for p in error.missing_permissions])
me = isinstance(error, app_commands.BotMissingPermissions)
await send(
self.babel(inter, 'missingperms', me=me, perms=permlist), **kwargs
)
return
if isinstance(error, app_commands.CommandInvokeError):
if isinstance(error.original, self.bot.auth.AuthError):
await send(str(error.original), **kwargs)
return
await send(
self.babel(inter, 'commanderror', error=str(error.original)), **kwargs
)
traceback.print_exception(type(error.original), error.original, error.original.__traceback__)
elif isinstance(error, (app_commands.CheckFailure, commands.CheckAnyFailure)):
print("Unhandled error;", error)
return
except asyncio.TimeoutError:
print(
"Unable to handle error in command",
inter.command.name if inter.command else 'UNKNOWN COMMAND',
"because the interaction timed out."
)
print(error)
async def setup(bot:MerelyBot):
""" Bind this cog to the bot """
await bot.add_cog(Error(bot))