Merge pull request #183 from classabbyamp/5c-errhandling

Improved error handling in commands
This commit is contained in:
0x5c 2020-01-28 05:51:12 -05:00 committed by GitHub
commit 74327378b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 54 additions and 86 deletions

View File

@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- All currently-available pools can now be accessed by the `hamstudy` command.
- The `hamstudy` command now uses the syntax `?hamstudy <country> <pool>`.
- Replaced `hamstudyanswer` command with answering by reaction.
- Removed all generic error handling from commands.
### Fixed
- Fixed ditto marks (") appearing in the ae7q call command.
- Fixed issue where incorrect table was parsed in ae7q call command.

View File

@ -16,6 +16,8 @@ from datetime import datetime
from pathlib import Path
from types import SimpleNamespace
import aiohttp
import discord
import discord.ext.commands as commands
@ -95,6 +97,18 @@ class ImagesGroup(collections.abc.Mapping):
return str(self._images)
# --- Exceptions ---
class BotHTTPError(Exception):
"""Raised whan a requests fails (status != 200) in a command."""
def __init__(self, response: aiohttp.ClientResponse):
msg = f"Request failed: {response.status} {response.reason}"
super().__init__(msg)
self.response = response
self.status = response.status
self.reason = response.reason
# --- Converters ---
class GlobalChannelConverter(commands.IDConverter):

View File

@ -44,11 +44,7 @@ class AE7QCog(commands.Cog):
async with self.session.get(base_url + callsign) as resp:
if resp.status != 200:
embed.title = "Error in AE7Q call command"
embed.description = 'Could not load AE7Q'
embed.colour = cmn.colours.bad
await ctx.send(embed=embed)
return
raise cmn.BotHTTPError(resp)
page = await resp.text()
soup = BeautifulSoup(page, features="html.parser")
@ -114,11 +110,7 @@ class AE7QCog(commands.Cog):
async with self.session.get(base_url + callsign) as resp:
if resp.status != 200:
embed.title = "Error in AE7Q trustee command"
embed.description = 'Could not load AE7Q'
embed.colour = cmn.colours.bad
await ctx.send(embed=embed)
return
raise cmn.BotHTTPError(resp)
page = await resp.text()
soup = BeautifulSoup(page, features="html.parser")
@ -186,11 +178,7 @@ class AE7QCog(commands.Cog):
async with self.session.get(base_url + callsign) as resp:
if resp.status != 200:
embed.title = "Error in AE7Q applications command"
embed.description = 'Could not load AE7Q'
embed.colour = cmn.colours.bad
await ctx.send(embed=embed)
return
raise cmn.BotHTTPError(resp)
page = await resp.text()
soup = BeautifulSoup(page, features="html.parser")
@ -245,7 +233,8 @@ class AE7QCog(commands.Cog):
await ctx.send(embed=embed)
"""
pass
raise NotImplementedError("Application history lookup not yet supported. "
"Check back in a later version of the bot.")
@_ae7q_lookup.command(name="frn", aliases=["f"], category=cmn.cat.lookup)
async def _ae7q_frn(self, ctx: commands.Context, frn: str):
@ -261,11 +250,7 @@ class AE7QCog(commands.Cog):
async with self.session.get(base_url + frn) as resp:
if resp.status != 200:
embed.title = "Error in AE7Q frn command"
embed.description = 'Could not load AE7Q'
embed.colour = cmn.colours.bad
await ctx.send(embed=embed)
return
raise cmn.BotHTTPError(resp)
page = await resp.text()
soup = BeautifulSoup(page, features="html.parser")
@ -328,11 +313,7 @@ class AE7QCog(commands.Cog):
async with self.session.get(base_url + licensee_id) as resp:
if resp.status != 200:
embed.title = "Error in AE7Q licensee command"
embed.description = 'Could not load AE7Q'
embed.colour = cmn.colours.bad
await ctx.send(embed=embed)
return
raise cmn.BotHTTPError(resp)
page = await resp.text()
soup = BeautifulSoup(page, features="html.parser")

View File

@ -24,27 +24,27 @@ class GridCog(commands.Cog):
with negative being latitude South and longitude West.'''
with ctx.typing():
grid = "**"
try:
latf = float(lat) + 90
lonf = float(lon) + 180
if 0 <= latf <= 180 and 0 <= lonf <= 360:
grid += chr(ord('A') + int(lonf / 20))
grid += chr(ord('A') + int(latf / 10))
grid += chr(ord('0') + int((lonf % 20)/2))
grid += chr(ord('0') + int((latf % 10)/1))
grid += chr(ord('a') + int((lonf - (int(lonf/2)*2)) / (5/60)))
grid += chr(ord('a') + int((latf - (int(latf/1)*1)) / (2.5/60)))
grid += "**"
embed = cmn.embed_factory(ctx)
embed.title = f'Maidenhead Grid Locator for {float(lat):.6f}, {float(lon):.6f}'
embed.description = grid
embed.colour = cmn.colours.good
else:
raise ValueError('Out of range.')
except ValueError as err:
latf = float(lat) + 90
lonf = float(lon) + 180
if 0 <= latf <= 180 and 0 <= lonf <= 360:
grid += chr(ord('A') + int(lonf / 20))
grid += chr(ord('A') + int(latf / 10))
grid += chr(ord('0') + int((lonf % 20)/2))
grid += chr(ord('0') + int((latf % 10)/1))
grid += chr(ord('a') + int((lonf - (int(lonf/2)*2)) / (5/60)))
grid += chr(ord('a') + int((latf - (int(latf/1)*1)) / (2.5/60)))
grid += "**"
embed = cmn.embed_factory(ctx)
embed.title = f'Maidenhead Grid Locator for {float(lat):.6f}, {float(lon):.6f}'
embed.description = grid
embed.colour = cmn.colours.good
else:
embed = cmn.embed_factory(ctx)
embed.title = f'Error generating grid square for {lat}, {lon}.'
embed.description = str(err)
embed.description = ("Coordinates out of range.\n"
"The valid ranges are:\n"
"- Latitude: `-90` to `+90`\n"
"- Longitude: `-180` to `+180`")
embed.colour = cmn.colours.bad
await ctx.send(embed=embed)

View File

@ -90,10 +90,7 @@ class ImageCog(commands.Cog):
embed.colour = cmn.colours.good
async with self.session.get(self.gl_url) as resp:
if resp.status != 200:
embed.description = 'Could not download file...'
embed.colour = cmn.colours.bad
await ctx.send(embed=embed)
return
raise cmn.BotHTTPError(resp)
data = io.BytesIO(await resp.read())
embed.set_image(url=f'attachment://greyline.jpg')
await ctx.send(embed=embed, file=discord.File(data, 'greyline.jpg'))

View File

@ -68,7 +68,7 @@ class MorseCog(commands.Cog):
weight += len(cw_char) * 2 + 2
except KeyError:
embed.title = 'Error in calculation of CW weight'
embed.description = f'Unknown character {char} in callsign'
embed.description = f'Unknown character `{char}` in message'
embed.colour = cmn.colours.bad
await ctx.send(embed=embed)
return

View File

@ -110,11 +110,7 @@ class StudyCog(commands.Cog):
async with self.session.get(f'https://hamstudy.org/pools/{pool}') as resp:
if resp.status != 200:
embed.title = 'Error in HamStudy command'
embed.description = 'Could not load questions'
embed.colour = cmn.colours.bad
await ctx.send(embed=embed)
return
raise cmn.BotHTTPError(resp)
pool = json.loads(await resp.read())['pool']
# Select a question
@ -172,7 +168,7 @@ class StudyCog(commands.Cog):
async def hamstudy_get_pools(self):
async with self.session.get('https://hamstudy.org/pools/') as resp:
if resp.status != 200:
raise ConnectionError
raise cmn.BotHTTPError(resp)
else:
pools_dict = json.loads(await resp.read())

View File

@ -34,10 +34,7 @@ class WeatherCog(commands.Cog):
embed.colour = cmn.colours.good
async with self.session.get('http://www.hamqsl.com/solarsun.php') as resp:
if resp.status != 200:
embed.description = 'Could not download file...'
embed.colour = cmn.colours.bad
await ctx.send(embed=embed)
return
raise cmn.BotHTTPError(resp)
data = io.BytesIO(await resp.read())
embed.set_image(url=f'attachment://condx.png')
await ctx.send(embed=embed, file=discord.File(data, 'condx.png'))
@ -84,10 +81,7 @@ See help for weather command for possible location types. Add a `-c` or `-f` to
loc = loc.replace(' ', '+')
async with self.session.get(f'http://wttr.in/{loc}_{units}pnFQ.png') as resp:
if resp.status != 200:
embed.description = 'Could not download file...'
embed.colour = cmn.colours.bad
await ctx.send(embed=embed)
return
raise cmn.BotHTTPError(resp)
data = io.BytesIO(await resp.read())
embed.set_image(url=f'attachment://wttr_forecast.png')
await ctx.send(embed=embed, file=discord.File(data, 'wttr_forecast.png'))
@ -118,10 +112,7 @@ See help for weather command for possible location types. Add a `-c` or `-f` to
loc = loc.replace(' ', '+')
async with self.session.get(f'http://wttr.in/{loc}_0{units}pnFQ.png') as resp:
if resp.status != 200:
embed.description = 'Could not download file...'
embed.colour = cmn.colours.bad
await ctx.send(embed=embed)
return
raise cmn.BotHTTPError(resp)
data = io.BytesIO(await resp.read())
embed.set_image(url=f'attachment://wttr_now.png')
await ctx.send(embed=embed, file=discord.File(data, 'wttr_now.png'))

24
main.py
View File

@ -103,12 +103,8 @@ async def _extctl_list(ctx: commands.Context):
@_extctl.command(name="load", aliases=["ld"])
async def _extctl_load(ctx: commands.Context, extension: str):
try:
bot.load_extension(ext_dir + "." + extension)
await cmn.add_react(ctx.message, cmn.emojis.check_mark)
except commands.ExtensionError as ex:
embed = cmn.error_embed_factory(ctx, ex, bot.qrm.debug_mode)
await ctx.send(embed=embed)
bot.load_extension(ext_dir + "." + extension)
await cmn.add_react(ctx.message, cmn.emojis.check_mark)
@_extctl.command(name="reload", aliases=["rl", "r", "relaod"])
@ -117,22 +113,14 @@ async def _extctl_reload(ctx: commands.Context, extension: str):
pika = bot.get_emoji(opt.pika)
if pika:
await cmn.add_react(ctx.message, pika)
try:
bot.reload_extension(ext_dir + "." + extension)
await cmn.add_react(ctx.message, cmn.emojis.check_mark)
except commands.ExtensionError as ex:
embed = cmn.error_embed_factory(ctx, ex, bot.qrm.debug_mode)
await ctx.send(embed=embed)
bot.reload_extension(ext_dir + "." + extension)
await cmn.add_react(ctx.message, cmn.emojis.check_mark)
@_extctl.command(name="unload", aliases=["ul"])
async def _extctl_unload(ctx: commands.Context, extension: str):
try:
bot.unload_extension(ext_dir + "." + extension)
await cmn.add_react(ctx.message, cmn.emojis.check_mark)
except commands.ExtensionError as ex:
embed = cmn.error_embed_factory(ctx, ex, bot.qrm.debug_mode)
await ctx.send(embed=embed)
bot.unload_extension(ext_dir + "." + extension)
await cmn.add_react(ctx.message, cmn.emojis.check_mark)
# --- Events ---