mirror of
https://github.com/miaowware/qrm2.git
synced 2024-11-26 09:48:41 -05:00
Better command error handling
- Added handling for all subclasses of CommandError - Added more emojis - Renamed some emojis - debug_mode -> bot.qrm.debug_mode Fixes #22 Co-authored-by: Abigail Gold <dev@kb6.ee>
This commit is contained in:
parent
70505f10f6
commit
0615df0829
@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
### Added
|
||||
- Flag emojis to commands with countries.
|
||||
- Image attribution and description to "image" commands.
|
||||
- Better user-facing command error handling.
|
||||
- New key in options.py: pika.
|
||||
|
||||
|
||||
|
13
common.py
13
common.py
@ -42,8 +42,12 @@ cat = SimpleNamespace(lookup='Information Lookup',
|
||||
study='Exam Study',
|
||||
weather='Land and Space Weather')
|
||||
|
||||
emojis = SimpleNamespace(good='✅',
|
||||
bad='❌')
|
||||
emojis = SimpleNamespace(check_mark='✅',
|
||||
x='❌',
|
||||
warning='⚠️',
|
||||
question='❓',
|
||||
no_entry='⛔',
|
||||
bangbang='‼️')
|
||||
|
||||
paths = SimpleNamespace(data=Path("./data/"),
|
||||
resources=Path("./resources/"),
|
||||
@ -106,7 +110,7 @@ def error_embed_factory(ctx: commands.Context, exception: Exception, debug_mode:
|
||||
else:
|
||||
fmtd_ex = traceback.format_exception_only(exception.__class__, exception)
|
||||
embed = embed_factory(ctx)
|
||||
embed.title = "Error"
|
||||
embed.title = "⚠️ Error"
|
||||
embed.description = "```\n" + '\n'.join(fmtd_ex) + "```"
|
||||
embed.colour = colours.bad
|
||||
return embed
|
||||
@ -124,5 +128,4 @@ async def add_react(msg: discord.Message, react: str):
|
||||
async def check_if_owner(ctx: commands.Context):
|
||||
if ctx.author.id in opt.owners_uids:
|
||||
return True
|
||||
await add_react(ctx.message, emojis.bad)
|
||||
return False
|
||||
raise commands.NotOwner
|
||||
|
58
main.py
58
main.py
@ -8,6 +8,9 @@ This file is part of discord-qrm2 and is released under the terms of the GNU
|
||||
General Public License, version 2.
|
||||
"""
|
||||
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
from datetime import time, datetime
|
||||
import random
|
||||
from types import SimpleNamespace
|
||||
@ -42,6 +45,8 @@ bot = commands.Bot(command_prefix=opt.prefix,
|
||||
bot.qrm = SimpleNamespace()
|
||||
bot.qrm.session = aiohttp.ClientSession(headers={'User-Agent': f'discord-qrm2/{info.release}'})
|
||||
|
||||
bot.qrm.debug_mode = debug_mode
|
||||
|
||||
|
||||
# --- Commands ---
|
||||
|
||||
@ -51,7 +56,7 @@ async def _restart_bot(ctx: commands.Context):
|
||||
"""Restarts the bot."""
|
||||
await bot.qrm.session.close()
|
||||
global exit_code
|
||||
await cmn.add_react(ctx.message, cmn.emojis.good)
|
||||
await cmn.add_react(ctx.message, cmn.emojis.check_mark)
|
||||
print(f"[**] Restarting! Requested by {ctx.author}.")
|
||||
exit_code = 42 # Signals to the wrapper script that the bot needs to be restarted.
|
||||
await bot.logout()
|
||||
@ -63,7 +68,7 @@ async def _shutdown_bot(ctx: commands.Context):
|
||||
"""Shuts down the bot."""
|
||||
await bot.qrm.session.close()
|
||||
global exit_code
|
||||
await cmn.add_react(ctx.message, cmn.emojis.good)
|
||||
await cmn.add_react(ctx.message, cmn.emojis.check_mark)
|
||||
print(f"[**] Shutting down! Requested by {ctx.author}.")
|
||||
exit_code = 0 # Signals to the wrapper script that the bot should not be restarted.
|
||||
await bot.logout()
|
||||
@ -92,9 +97,9 @@ async def _extctl_list(ctx: commands.Context):
|
||||
async def _extctl_load(ctx: commands.Context, extension: str):
|
||||
try:
|
||||
bot.load_extension(ext_dir + "." + extension)
|
||||
await cmn.add_react(ctx.message, cmn.emojis.good)
|
||||
await cmn.add_react(ctx.message, cmn.emojis.check_mark)
|
||||
except commands.ExtensionError as ex:
|
||||
embed = cmn.error_embed_factory(ctx, ex, debug_mode)
|
||||
embed = cmn.error_embed_factory(ctx, ex, bot.qrm.debug_mode)
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
|
||||
@ -106,9 +111,9 @@ async def _extctl_reload(ctx: commands.Context, extension: str):
|
||||
await cmn.add_react(ctx.message, pika)
|
||||
try:
|
||||
bot.reload_extension(ext_dir + "." + extension)
|
||||
await cmn.add_react(ctx.message, cmn.emojis.good)
|
||||
await cmn.add_react(ctx.message, cmn.emojis.check_mark)
|
||||
except commands.ExtensionError as ex:
|
||||
embed = cmn.error_embed_factory(ctx, ex, debug_mode)
|
||||
embed = cmn.error_embed_factory(ctx, ex, bot.qrm.debug_mode)
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
|
||||
@ -116,9 +121,9 @@ async def _extctl_reload(ctx: commands.Context, extension: str):
|
||||
async def _extctl_unload(ctx: commands.Context, extension: str):
|
||||
try:
|
||||
bot.unload_extension(ext_dir + "." + extension)
|
||||
await cmn.add_react(ctx.message, cmn.emojis.good)
|
||||
await cmn.add_react(ctx.message, cmn.emojis.check_mark)
|
||||
except commands.ExtensionError as ex:
|
||||
embed = cmn.error_embed_factory(ctx, ex, debug_mode)
|
||||
embed = cmn.error_embed_factory(ctx, ex, bot.qrm.debug_mode)
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
|
||||
@ -146,6 +151,37 @@ async def on_message(message):
|
||||
await bot.process_commands(message)
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_command_error(ctx: commands.Context, err: commands.CommandError):
|
||||
if isinstance(err, commands.UserInputError):
|
||||
await cmn.add_react(ctx.message, cmn.emojis.warning)
|
||||
await ctx.send_help(ctx.command)
|
||||
elif isinstance(err, commands.CommandNotFound) and not ctx.invoked_with.startswith("?"):
|
||||
await cmn.add_react(ctx.message, cmn.emojis.question)
|
||||
elif isinstance(err, commands.CheckFailure):
|
||||
# Add handling of other subclasses of CheckFailure as needed.
|
||||
if isinstance(err, commands.NotOwner):
|
||||
await cmn.add_react(ctx.message, cmn.emojis.no_entry)
|
||||
else:
|
||||
await cmn.add_react(ctx.message, cmn.emojis.x)
|
||||
elif isinstance(err, commands.DisabledCommand):
|
||||
await cmn.add_react(ctx.message, cmn.emojis.bangbang)
|
||||
elif isinstance(err, (commands.CommandInvokeError, commands.ConversionError)):
|
||||
# Emulating discord.py's default beaviour.
|
||||
print('Ignoring exception in command {}:'.format(ctx.command), file=sys.stderr)
|
||||
traceback.print_exception(type(err), err, err.__traceback__, file=sys.stderr)
|
||||
|
||||
embed = cmn.error_embed_factory(ctx, err.original, bot.qrm.debug_mode)
|
||||
embed.description += f"\n`{type(err).__name__}`"
|
||||
await cmn.add_react(ctx.message, cmn.emojis.warning)
|
||||
await ctx.send(embed=embed)
|
||||
else:
|
||||
# Emulating discord.py's default beaviour. (safest bet)
|
||||
print('Ignoring exception in command {}:'.format(ctx.command), file=sys.stderr)
|
||||
traceback.print_exception(type(err), err, err.__traceback__, file=sys.stderr)
|
||||
await cmn.add_react(ctx.message, cmn.emojis.warning)
|
||||
|
||||
|
||||
# --- Tasks ---
|
||||
|
||||
@tasks.loop(minutes=5)
|
||||
@ -194,19 +230,19 @@ try:
|
||||
|
||||
except discord.LoginFailure as ex:
|
||||
# Miscellaneous authentications errors: borked token and co
|
||||
if debug_mode:
|
||||
if bot.qrm.debug_mode:
|
||||
raise
|
||||
raise SystemExit("Error: Failed to authenticate: {}".format(ex))
|
||||
|
||||
except discord.ConnectionClosed as ex:
|
||||
# When the connection to the gateway (websocket) is closed
|
||||
if debug_mode:
|
||||
if bot.qrm.debug_mode:
|
||||
raise
|
||||
raise SystemExit("Error: Discord gateway connection closed: [Code {}] {}".format(ex.code, ex.reason))
|
||||
|
||||
except ConnectionResetError as ex:
|
||||
# More generic connection reset error
|
||||
if debug_mode:
|
||||
if bot.qrm.debug_mode:
|
||||
raise
|
||||
raise SystemExit("ConnectionResetError: {}".format(ex))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user