Improved error handling for MySQL connection issues and added support to PM users on certain errors
parent
f801016a5b
commit
7532912d21
|
@ -7,6 +7,7 @@ def create_config(config):
|
|||
'Status': '',
|
||||
'Prefix': '?',
|
||||
'Bot_Mod': ''
|
||||
'Error_Users: '''
|
||||
}
|
||||
config['SQL'] = {'Dialect+Driver': 'mysql+mysqldb',
|
||||
'Username': '',
|
||||
|
@ -51,6 +52,7 @@ class Config:
|
|||
self.prefix = self.config['Discord']['Prefix']
|
||||
self.dynmap_url = self.config['Minecraft']['Dynmap_Url']
|
||||
self.bot_mod = self.config['Discord']['Bot_Mod'].split(',')
|
||||
self.error_users = self.config['Discord']['Error_Users'].split(',')
|
||||
self.count = int(self.config['Logging']['Count'])
|
||||
self.rotation_duration = int(self.config['Logging']['Rotation_Duration'])
|
||||
self.special_name_list = dict(self.config.items('Special Names'))
|
||||
|
|
38
bot.py
38
bot.py
|
@ -4,15 +4,14 @@ import logging
|
|||
from discord import Game
|
||||
from discord.ext import commands
|
||||
from discord.utils import oauth_url
|
||||
from sqlalchemy.exc import OperationalError
|
||||
|
||||
from BotConfig import *
|
||||
from BotConfig import bot_config
|
||||
from BotErrors import *
|
||||
from Commands import Commands
|
||||
from DatabaseModels import Player
|
||||
from MinecraftAccountInfoGrabber import *
|
||||
|
||||
from pymysql.err import OperationalError
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
description = '''
|
||||
|
@ -27,11 +26,7 @@ If have a suggestion or if something is borked, you can PM my ding dong of a cre
|
|||
'''
|
||||
|
||||
bad_error_message = 'OOPSIE WOOPSIE!! Uwu We made a fucky wucky!! A wittle fucko boingo! The admins at our ' \
|
||||
'headquarters are working VEWY HAWD to fix this! (Error in command {}: {})'
|
||||
|
||||
|
||||
bot = commands.Bot(command_prefix=bot_config.prefix, description=description, case_insensitive=True)
|
||||
bot_commands = Commands()
|
||||
'headquarters are working VEWY HAWD to fix this! (Error in command {})'
|
||||
|
||||
extensions = ['cogs.Add_Commands',
|
||||
'cogs.Delete_Commands',
|
||||
|
@ -39,6 +34,13 @@ extensions = ['cogs.Add_Commands',
|
|||
'cogs.Search_Commands',
|
||||
'cogs.Admin_Commands']
|
||||
|
||||
bot = commands.Bot(command_prefix=bot_config.prefix, description=description, case_insensitive=True)
|
||||
|
||||
try:
|
||||
bot_commands = Commands()
|
||||
except OperationalError:
|
||||
logger.info('Could not connect to MySQL server.')
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
|
@ -54,7 +56,7 @@ async def on_command(command, ctx):
|
|||
if ctx.invoked_subcommand is None:
|
||||
subcommand = ""
|
||||
else:
|
||||
subcommand = ":"+ctx.invoked_subcommand
|
||||
subcommand = ":" + ctx.invoked_subcommand
|
||||
|
||||
logger.info("User %s, used command %s%s with context: %s", ctx.message.author, command, subcommand, ctx.args)
|
||||
|
||||
|
@ -69,7 +71,7 @@ async def on_command_error(error, ctx):
|
|||
elif isinstance(error, commands.CommandOnCooldown):
|
||||
return
|
||||
elif isinstance(error, commands.UserInputError):
|
||||
error_str = 'Invalid syntax for **{}** you ding dong:'\
|
||||
error_str = 'Invalid syntax for **{}** you ding dong:' \
|
||||
.format(ctx.invoked_with, ctx.invoked_with)
|
||||
|
||||
pages = bot.formatter.format_help_for(ctx, ctx.command)
|
||||
|
@ -84,23 +86,31 @@ async def on_command_error(error, ctx):
|
|||
elif isinstance(error.original, PlayerNotFound):
|
||||
error_str = 'Make sure to use ?register first you ding dong.'
|
||||
elif isinstance(error.original, EntryNameNotUniqueError):
|
||||
error_str = 'An entry in the database already has that name ding dong.'
|
||||
error_str = 'An entry in the database already has that name you ding dong.'
|
||||
elif isinstance(error.original, DatabaseValueError):
|
||||
error_str = 'Use a shorter name or a smaller value, dong ding.'
|
||||
elif isinstance(error.original, NotOnServerError):
|
||||
error_str = 'Command needs to be run on 24CC. Run this command there whoever you are.'.format()
|
||||
elif isinstance(error.original, OperationalError):
|
||||
await send_error_message('Error connecting to the MySQL server, is it offline?')
|
||||
error_str = 'Database connection issue, looks like some admin has to fix something.'.format()
|
||||
else:
|
||||
await send_error_message('Geoffrey encountered unhandled exception: {}. Context:'.format(error, ctx.args))
|
||||
|
||||
logger.error("Geoffrey encountered unhandled exception: %s", error)
|
||||
error_str = bad_error_message.format(ctx.invoked_with, error)
|
||||
error_str = bad_error_message.format(ctx.invoked_with)
|
||||
|
||||
await bot.send_message(ctx.message.channel, '{} **Error Running Command:** {}'.format(ctx.message.author.mention,
|
||||
error_str))
|
||||
|
||||
|
||||
async def send_error_message(msg):
|
||||
for user_id in bot_config.error_users:
|
||||
user = await bot.get_user_info(user_id)
|
||||
await bot.send_message(user, msg)
|
||||
|
||||
|
||||
async def username_update():
|
||||
session = None
|
||||
await bot.wait_until_ready()
|
||||
while not bot.is_closed:
|
||||
session = bot_commands.interface.database.Session()
|
||||
|
@ -118,6 +128,7 @@ async def username_update():
|
|||
logger.info("Username lookup error.")
|
||||
session.rollback()
|
||||
except OperationalError:
|
||||
await send_error_message('Error connecting to the MySQL server, is it offline?')
|
||||
logger.info("MySQL connection error")
|
||||
finally:
|
||||
session.close()
|
||||
|
@ -126,6 +137,7 @@ async def username_update():
|
|||
|
||||
def start_bot():
|
||||
try:
|
||||
Commands()
|
||||
for extension in extensions:
|
||||
try:
|
||||
bot.load_extension(extension)
|
||||
|
|
|
@ -15,7 +15,7 @@ class Search_Commands:
|
|||
|
||||
@commands.command(pass_context=True)
|
||||
@commands.cooldown(5, 60, commands.BucketType.user)
|
||||
async def find(self, ctx, * args):
|
||||
async def find(self, ctx, *args):
|
||||
"""
|
||||
Finds all the locations and tunnels matching the search term
|
||||
?find [Search]
|
||||
|
@ -28,10 +28,11 @@ class Search_Commands:
|
|||
|
||||
result = bot_commands.find(search)
|
||||
|
||||
await self.bot.say('{}, The following entries match **{}**:\n{}'.format(ctx.message.author.mention, search, result))
|
||||
await self.bot.say(
|
||||
'{}, The following entries match **{}**:\n{}'.format(ctx.message.author.mention, search, result))
|
||||
except LocationLookUpError:
|
||||
await self.bot.say('{}, no matches to **{}** were found in the database.'.format(ctx.message.author.mention, search))
|
||||
|
||||
await self.bot.say(
|
||||
'{}, no matches to **{}** were found in the database.'.format(ctx.message.author.mention, search))
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
@commands.cooldown(5, 60, commands.BucketType.user)
|
||||
|
@ -43,15 +44,15 @@ class Search_Commands:
|
|||
try:
|
||||
result = bot_commands.tunnel(player)
|
||||
|
||||
await self.bot.say('{}, **{}** owns the following tunnels: \n{}'.format(ctx.message.author.mention, player, result))
|
||||
await self.bot.say(
|
||||
'{}, **{}** owns the following tunnels: \n{}'.format(ctx.message.author.mention, player, result))
|
||||
except LocationLookUpError:
|
||||
await self.bot.say('{}, no tunnels for **{}** were found in the database.'
|
||||
.format(ctx.message.author.mention, player))
|
||||
|
||||
.format(ctx.message.author.mention, player))
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
@commands.cooldown(5, 60, commands.BucketType.user)
|
||||
async def find_around(self, ctx, x_pos: int, z_pos: int, * args):
|
||||
async def find_around(self, ctx, x_pos: int, z_pos: int, *args):
|
||||
"""
|
||||
Finds all the locations around a certain point.
|
||||
The radius defaults to 200 blocks if no value is given.
|
||||
|
@ -84,10 +85,11 @@ class Search_Commands:
|
|||
ctx.message.author.mention, radius, base_string))
|
||||
else:
|
||||
await self.bot.say('{}, there are no locations within {} blocks of that point'
|
||||
.format(ctx.message.author.mention, radius))
|
||||
.format(ctx.message.author.mention, radius))
|
||||
except ValueError:
|
||||
await self.bot.say('{}, invalid radius, the radius must be a whole number.'.format(ctx.message.author.mention,
|
||||
radius))
|
||||
await self.bot.say(
|
||||
'{}, invalid radius, the radius must be a whole number.'.format(ctx.message.author.mention,
|
||||
radius))
|
||||
except InvalidDimError:
|
||||
await self.bot.say('{}, {} is an invalid dimension.'.format(ctx.message.author.mention, dimension))
|
||||
|
||||
|
@ -100,13 +102,14 @@ class Search_Commands:
|
|||
"""
|
||||
try:
|
||||
result = bot_commands.selling(item_name)
|
||||
await self.bot.say('{}, the following shops sell **{}**: \n{}'.format(ctx.message.author.mention, item_name, result))
|
||||
await self.bot.say(
|
||||
'{}, the following shops sell **{}**: \n{}'.format(ctx.message.author.mention, item_name, result))
|
||||
except ItemNotFound:
|
||||
await self.bot.say('{}, no shop sells **{}**.'.format(ctx.message.author.mention, item_name))
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
@commands.cooldown(5, 60, commands.BucketType.user)
|
||||
async def info(self, ctx, * args):
|
||||
async def info(self, ctx, *args):
|
||||
"""
|
||||
Displays info about a location.
|
||||
If the location is a shop, it displays the shop's inventory.
|
||||
|
|
Loading…
Reference in New Issue