Error Handling, Online Util

This commit is contained in:
Adriene Hutchins 2020-03-02 18:37:34 -05:00
parent 8adc005f50
commit 830adece17
4 changed files with 97 additions and 54 deletions

View file

@ -19,6 +19,7 @@ import io
import inspect import inspect
import textwrap import textwrap
import subprocess import subprocess
from extensions.utils import online
class Developer(commands.Cog): class Developer(commands.Cog):
@ -29,6 +30,7 @@ class Developer(commands.Cog):
# Main Stuff # Main Stuff
self.bot = bot self.bot = bot
self.request = bot.request self.request = bot.request
self.online = bot.online
self.emoji = "\U0001F3D7" self.emoji = "\U0001F3D7"
# Repl/Eval Stuff # Repl/Eval Stuff
@ -54,19 +56,6 @@ class Developer(commands.Cog):
'^', '^',
type(err).__name__) type(err).__name__)
async def _post_to_hastebin(self, string):
"""Posts a string to hastebin."""
url = "https://hastebin.com/documents"
data = string.encode('utf-8')
async with self.request.post(url=url, data=data) as haste_response:
haste_key = (await haste_response.json())['key']
haste_url = f"http://hastebin.com/{haste_key}"
# data = {'sprunge': ''}
# data['sprunge'] = string
# haste_url = await self.aioclient.post(url='http://sprunge.us',
# data=data)
return haste_url
@commands.group(name='shell', @commands.group(name='shell',
aliases=['ipython', 'repl', 'longexec'], aliases=['ipython', 'repl', 'longexec'],
invoke_without_command=True) invoke_without_command=True)
@ -161,7 +150,7 @@ class Developer(commands.Cog):
item, item,
history[item]) history[item])
haste_url = await self._post_to_hastebin(history_string) haste_url = await self.online.hastebin(history_string)
return_msg = "[`Leaving shell session. "\ return_msg = "[`Leaving shell session. "\
"History hosted on hastebin.`]({})".format( "History hosted on hastebin.`]({})".format(
haste_url) haste_url)
@ -201,7 +190,7 @@ class Developer(commands.Cog):
if len(cleaned) > 800: if len(cleaned) > 800:
cleaned = "<Too big to be printed>" cleaned = "<Too big to be printed>"
if len(return_msg) > 800: if len(return_msg) > 800:
haste_url = await self._post_to_hastebin(return_msg) haste_url = await self.online.hastebin(return_msg)
return_msg = "[`SyntaxError too big to be printed. "\ return_msg = "[`SyntaxError too big to be printed. "\
"Hosted on hastebin.`]({})".format( "Hosted on hastebin.`]({})".format(
haste_url) haste_url)
@ -253,7 +242,7 @@ class Developer(commands.Cog):
try: try:
if fmt is not None: if fmt is not None:
if len(fmt) >= 800: if len(fmt) >= 800:
haste_url = await self._post_to_hastebin(fmt) haste_url = await self.online.hastebin(fmt)
self.repl_embeds[shell].add_field( self.repl_embeds[shell].add_field(
name="`>>> {}`".format(cleaned), name="`>>> {}`".format(cleaned),
value="[`Content too big to be printed. " value="[`Content too big to be printed. "
@ -467,7 +456,7 @@ class Developer(commands.Cog):
if (len(result[0]) >= 1024): if (len(result[0]) >= 1024):
stdout = result[0].decode('utf-8') stdout = result[0].decode('utf-8')
string = string + f'[[STDOUT]]\n{stdout}' string = string + f'[[STDOUT]]\n{stdout}'
link = await self._post_to_hastebin(string) link = await self.online.hastebin(string)
await message.edit( await message.edit(
content=f":x: Content too long. {link}", content=f":x: Content too long. {link}",
embed=None) embed=None)
@ -476,7 +465,7 @@ class Developer(commands.Cog):
if (len(result[1]) >= 1024): if (len(result[1]) >= 1024):
stdout = result[0].decode('utf-8') stdout = result[0].decode('utf-8')
string = string + f'[[STDERR]]\n{stdout}' string = string + f'[[STDERR]]\n{stdout}'
link = await self._post_to_hastebin(string) link = await self.online.hastebin(string)
await message.edit( await message.edit(
content=f":x: Content too long. {link}", content=f":x: Content too long. {link}",
embed=None) embed=None)

View file

@ -67,7 +67,7 @@ class Search(commands.Cog):
) )
# Create the URL to make an API call to # Create the URL to make an API call to
call = f'{instance}/search?q={query}&format=json&language=en-US' call = f'{instance}search?q={query}&format=json&language=en-US'
# If a type is provided, add that type to the call URL # If a type is provided, add that type to the call URL
if category: if category:

View file

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# tacibot online util
# Provides utils for various online tools.
'''Online File'''
class Online():
def __init__(self, bot):
self.bot = bot
self.request = bot.request
async def hastebin(self, string):
"""Posts a string to hastebin."""
url = "https://hastebin.com/documents"
data = string.encode('utf-8')
async with self.request.post(url=url, data=data) as haste_response:
haste_key = (await haste_response.json())['key']
haste_url = f"http://hastebin.com/{haste_key}"
# data = {'sprunge': ''}
# data['sprunge'] = string
# haste_url = await self.aioclient.post(url='http://sprunge.us',
# data=data)
return haste_url
def setup(bot):
bot.online = Online(bot)

96
main.py
View file

@ -24,7 +24,7 @@ class Bot(commands.Bot):
"""Initializes the main parts of the bot.""" """Initializes the main parts of the bot."""
# Logging # Logging
print('Performing initialization...\n') print('Initializing...\n')
# Initializes parent class # Initializes parent class
super().__init__(self._get_prefix_new, **options) super().__init__(self._get_prefix_new, **options)
@ -44,31 +44,10 @@ class Bot(commands.Bot):
self.instances = f.read().split('\n') self.instances = f.read().split('\n')
# Logging # Logging
print('Initialization complete.\n\n')
def _init_extensions(self): def _init_extensions(self):
"""Initializes extensions.""" """Initializes extensions."""
# Extensions
for ext in os.listdir('extensions'):
if ext.endswith('.py'):
try:
bot.load_extension(f'extensions.{ext[:-3]}')
self.extensions_list.append(
f'extensions.{ext[:-3]}')
except Exception as e:
print(e)
# Models
for ext in os.listdir('extensions/models'):
if ext.endswith('.py'):
try:
bot.load_extension(f'extensions.models.{ext[:-3]}')
self.extensions_list.append(
f'extensions.models.{ext[:-3]}')
except Exception as e:
print(e)
# Utils # Utils
for ext in os.listdir('extensions/utils'): for ext in os.listdir('extensions/utils'):
if ext.endswith('.py'): if ext.endswith('.py'):
@ -79,6 +58,26 @@ class Bot(commands.Bot):
except Exception as e: except Exception as e:
print(e) print(e)
# Models
for ext in os.listdir('extensions/models'):
if ext.endswith('.py'):
try:
bot.load_extension(f'extensions.models.{ext[:-3]}')
self.extensions_list.append(
f'extensions.models.{ext[:-3]}')
except Exception as e:
print(e)
# Extensions
for ext in os.listdir('extensions'):
if ext.endswith('.py'):
try:
bot.load_extension(f'extensions.{ext[:-3]}')
self.extensions_list.append(
f'extensions.{ext[:-3]}')
except Exception as e:
print(e)
async def _get_prefix_new(self, bot, msg): async def _get_prefix_new(self, bot, msg):
"""More flexible check for prefix.""" """More flexible check for prefix."""
@ -95,6 +94,8 @@ class Bot(commands.Bot):
async def on_ready(self): async def on_ready(self):
"""Initializes the main portion of the bot once it has connected.""" """Initializes the main portion of the bot once it has connected."""
print('Connected.\n')
# Prerequisites # Prerequisites
if not hasattr(self, 'request'): if not hasattr(self, 'request'):
self.request = aiohttp.ClientSession() self.request = aiohttp.ClientSession()
@ -108,8 +109,10 @@ class Bot(commands.Bot):
if self.extensions_list == []: if self.extensions_list == []:
self._init_extensions() self._init_extensions()
print('Initialized.\n')
# Logging # Logging
msg = "CONNECTED!\n" msg = "ALL ENGINES GO!\n"
msg += "-----------------------------\n" msg += "-----------------------------\n"
msg += f"ACCOUNT: {bot.user}\n" msg += f"ACCOUNT: {bot.user}\n"
msg += f"OWNER: {self.appinfo.owner}\n" msg += f"OWNER: {self.appinfo.owner}\n"
@ -165,18 +168,34 @@ async def on_command_error(ctx, error):
# Provides a very pretty embed if something's actually a dev's fault. # Provides a very pretty embed if something's actually a dev's fault.
elif isinstance(error, commands.CommandInvokeError): elif isinstance(error, commands.CommandInvokeError):
# Prerequisites # Prerequisites
error = error.original original_error = error.original
_traceback = traceback.format_tb(error.__traceback__) traceback_orig = traceback.format_tb(original_error.__traceback__)
_traceback = ''.join(_traceback) traceback_orig = ''.join(traceback_orig)
appinfo = await bot.application_info() appinfo = await bot.application_info()
original_exc = traceback.format_exception(
type(original_error), original_error, original_error.__traceback__)
print(original_exc)
# Main Message # Main Message
embed_fallback = f"**An error occured: {type(error).__name__}. Please contact {appinfo.owner}.**" embed_fallback = f"**An error occured: {type(original_error).__name__}. Please contact {appinfo.owner}.**"
# Hastebins Traceback
try:
url = await bot.online.hastebin(
''.join(original_exc))
except Exception as e:
url = None
print(e)
# Embed Building # Embed Building
error_embed = discord.Embed( error_embed = discord.Embed(
title=f"{type(error).__name__}", title=(
f"{type(original_error).__name__} "
f"{'(Click for Hastebin)' if url else ''}"
),
url=url if url else None,
color=0xFF0000, color=0xFF0000,
description=( # TODO Change if has logging description=( # TODO Change if has logging
"This is (probably) a bug. This has not been automatically " "This is (probably) a bug. This has not been automatically "
@ -187,25 +206,32 @@ async def on_command_error(ctx, error):
trace_content = ( trace_content = (
"```py\n\nTraceback (most recent call last):" "```py\n\nTraceback (most recent call last):"
"\n{}{}: {}```").format( "\n{}{}: {}```").format(
_traceback, traceback_orig,
type(error).__name__, type(original_error).__name__,
error) original_error)
# Adds Traceback # Adds Traceback
error_embed.add_field( error_embed.add_field(
name="`{}` in command `{}`".format( name=(
type(error).__name__, ctx.command.qualified_name), f"`{type(original_error).__name__}` in "
f"command `{ctx.command.qualified_name}`"
),
value=(trace_content[:1018] + '...```') value=(trace_content[:1018] + '...```')
if len(trace_content) > 1024 if len(trace_content) > 1024
else trace_content) else trace_content
)
# Sending # Sending
await ctx.send(embed_fallback, embed=error_embed) await ctx.send(embed_fallback, embed=error_embed)
# If anything else goes wrong, just go ahead and send it in chat. # If anything else goes wrong, just go ahead and send it in chat.
else: else:
original_error = error
original_exc = traceback.format_exception(
type(original_error), original_error, original_error.__traceback__)
print(''.join(original_exc))
await ctx.send(error) await ctx.send(error)
# NOTE Bot Entry Point # NOTE Bot Entry Point
# Starts the bot # Starts the bot
print("Connecting...\n")
bot.run(bot.config['TOKEN']) bot.run(bot.config['TOKEN'])