Refactor error handling for system commands

This commit is contained in:
Ske 2018-09-09 20:50:53 +02:00
parent a079db8be0
commit e95d8a4e0d
3 changed files with 41 additions and 24 deletions

View File

@ -5,8 +5,7 @@ from datetime import datetime
import pluralkit.utils import pluralkit.utils
from pluralkit.bot import help from pluralkit.bot import help
from pluralkit.bot.commands import * from pluralkit.bot.commands import *
from pluralkit.errors import ExistingSystemError, DescriptionTooLongError, TagTooLongError, TagTooLongWithMembersError, \ from pluralkit.errors import ExistingSystemError, UnlinkingLastAccountError, PluralKitError, AccountAlreadyLinkedError
InvalidAvatarURLError, UnlinkingLastAccountError
logger = logging.getLogger("pluralkit.commands") logger = logging.getLogger("pluralkit.commands")
@ -25,9 +24,8 @@ async def new_system(ctx: CommandContext):
try: try:
await System.create_system(ctx.conn, ctx.message.author.id, system_name) await System.create_system(ctx.conn, ctx.message.author.id, system_name)
except ExistingSystemError: except ExistingSystemError as e:
return CommandError( return CommandError(e.message)
"You already have a system registered. To delete your system, use `pk;system delete`, or to unlink your system from this account, use `pk;system unlink`.")
return CommandSuccess("System registered! To begin adding members, use `pk;member new <name>`.") return CommandSuccess("System registered! To begin adding members, use `pk;member new <name>`.")
@ -55,21 +53,15 @@ async def system_set(ctx: CommandContext):
if property_name not in properties: if property_name not in properties:
return CommandError( return CommandError(
"Unknown property {}. Allowed properties are {}.".format(property_name, ", ".join(allowed_properties)), "Unknown property {}. Allowed properties are {}.".format(property_name, ", ".join(properties.keys())),
help=help.edit_system) help=help.edit_system)
value = ctx.remaining() or None value = ctx.remaining() or None
try: try:
await properties[property_name](ctx.conn, value) await properties[property_name](ctx.conn, value)
except DescriptionTooLongError: except PluralKitError as e:
return CommandError("You can't have a description longer than 1024 characters.") return CommandError(e.message)
except TagTooLongError:
return CommandError("You can't have a system tag longer than 32 characters.")
except TagTooLongWithMembersError as e:
return CommandError("The maximum length of a name plus the system tag is 32 characters. The following members would exceed the limit: {}. Please reduce the length of the tag, or rename the members.".format(", ".join(e.member_names)))
except InvalidAvatarURLError:
return CommandError("Invalid image URL.")
response = CommandSuccess("{} system {}.".format("Updated" if value else "Cleared", property_name)) response = CommandSuccess("{} system {}.".format("Updated" if value else "Cleared", property_name))
# if prop == "avatar" and value: # if prop == "avatar" and value:
@ -89,7 +81,7 @@ async def system_link(ctx: CommandContext):
# Make sure account doesn't already have a system # Make sure account doesn't already have a system
account_system = await System.get_by_account(ctx.conn, linkee.id) account_system = await System.get_by_account(ctx.conn, linkee.id)
if account_system: if account_system:
return CommandError("The mentioned account is already linked to a system (`{}`)".format(account_system.hid)) return CommandError(AccountAlreadyLinkedError(account_system).message)
if not await ctx.confirm_react(linkee, "{}, please confirm the link by clicking the ✅ reaction on this message.".format(linkee.mention)): if not await ctx.confirm_react(linkee, "{}, please confirm the link by clicking the ✅ reaction on this message.".format(linkee.mention)):
return CommandError("Account link cancelled.") return CommandError("Account link cancelled.")
@ -103,8 +95,8 @@ async def system_unlink(ctx: CommandContext):
try: try:
await system.unlink_account(ctx.conn, ctx.message.author.id) await system.unlink_account(ctx.conn, ctx.message.author.id)
except UnlinkingLastAccountError: except UnlinkingLastAccountError as e:
return CommandError("This is the only account on your system, so you can't unlink it.") return CommandError(e.message)
return CommandSuccess("Account unlinked.") return CommandSuccess("Account unlinked.")

View File

@ -1,36 +1,57 @@
from typing import Tuple
class PluralKitError(Exception): class PluralKitError(Exception):
pass def __init__(self, message):
self.message = message
self.help_page = None
def with_help(self, help_page: Tuple[str, str]):
self.help_page = help_page
class ExistingSystemError(PluralKitError): class ExistingSystemError(PluralKitError):
pass def __init__(self):
super().__init__("You already have a system registered. To delete your system, use `pk;system delete`, or to unlink your system from this account, use `pk;system unlink`.")
class DescriptionTooLongError(PluralKitError): class DescriptionTooLongError(PluralKitError):
pass def __init__(self):
super().__init__("You can't have a description longer than 1024 characters.")
class TagTooLongError(PluralKitError): class TagTooLongError(PluralKitError):
pass def __init__(self):
super().__init__("You can't have a system tag longer than 32 characters.")
class TagTooLongWithMembersError(PluralKitError): class TagTooLongWithMembersError(PluralKitError):
def __init__(self, member_names): def __init__(self, member_names):
super().__init__("The maximum length of a name plus the system tag is 32 characters. The following members would exceed the limit: {}. Please reduce the length of the tag, or rename the members.".format(", ".join(member_names)))
self.member_names = member_names self.member_names = member_names
class CustomEmojiError(PluralKitError): class CustomEmojiError(PluralKitError):
pass def __init__(self):
super().__init__("Due to a Discord limitation, custom emojis aren't supported. Please use a standard emoji instead.")
class InvalidAvatarURLError(PluralKitError): class InvalidAvatarURLError(PluralKitError):
pass def __init__(self):
super().__init__("Invalid image URL.")
class AccountInOwnSystemError(PluralKitError):
def __init__(self):
super().__init__("That account is already linked to your own system.")
class AccountAlreadyLinkedError(PluralKitError): class AccountAlreadyLinkedError(PluralKitError):
def __init__(self, existing_system): def __init__(self, existing_system):
super().__init__("The mentioned account is already linked to a system (`{}`)".format(existing_system.hid))
self.existing_system = existing_system self.existing_system = existing_system
class UnlinkingLastAccountError(PluralKitError): class UnlinkingLastAccountError(PluralKitError):
pass def __init__(self):
super().__init__("This is the only account on your system, so you can't unlink it.")

View File

@ -65,7 +65,11 @@ class System(namedtuple("System", ["id", "hid", "name", "description", "tag", "a
async def link_account(self, conn, new_account_id: str): async def link_account(self, conn, new_account_id: str):
existing_system = await System.get_by_account(conn, new_account_id) existing_system = await System.get_by_account(conn, new_account_id)
if existing_system: if existing_system:
if existing_system.id == self.id:
raise errors.AccountInOwnSystemError()
raise errors.AccountAlreadyLinkedError(existing_system) raise errors.AccountAlreadyLinkedError(existing_system)
await db.link_account(conn, self.id, new_account_id) await db.link_account(conn, self.id, new_account_id)