From 830adece17083e9e79ffd512a2ccdcd9a5a5005b Mon Sep 17 00:00:00 2001 From: Adriene Hutchins Date: Mon, 2 Mar 2020 18:37:34 -0500 Subject: [PATCH] Error Handling, Online Util --- extensions/developer.py | 25 +++------- extensions/search.py | 2 +- extensions/utils/online.py | 28 +++++++++++ main.py | 96 ++++++++++++++++++++++++-------------- 4 files changed, 97 insertions(+), 54 deletions(-) create mode 100644 extensions/utils/online.py diff --git a/extensions/developer.py b/extensions/developer.py index 99c63db..7e6a1e5 100644 --- a/extensions/developer.py +++ b/extensions/developer.py @@ -19,6 +19,7 @@ import io import inspect import textwrap import subprocess +from extensions.utils import online class Developer(commands.Cog): @@ -29,6 +30,7 @@ class Developer(commands.Cog): # Main Stuff self.bot = bot self.request = bot.request + self.online = bot.online self.emoji = "\U0001F3D7" # Repl/Eval Stuff @@ -54,19 +56,6 @@ class Developer(commands.Cog): '^', 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', aliases=['ipython', 'repl', 'longexec'], invoke_without_command=True) @@ -161,7 +150,7 @@ class Developer(commands.Cog): 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. "\ "History hosted on hastebin.`]({})".format( haste_url) @@ -201,7 +190,7 @@ class Developer(commands.Cog): if len(cleaned) > 800: cleaned = "" 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. "\ "Hosted on hastebin.`]({})".format( haste_url) @@ -253,7 +242,7 @@ class Developer(commands.Cog): try: if fmt is not None: 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( name="`>>> {}`".format(cleaned), value="[`Content too big to be printed. " @@ -467,7 +456,7 @@ class Developer(commands.Cog): if (len(result[0]) >= 1024): stdout = result[0].decode('utf-8') string = string + f'[[STDOUT]]\n{stdout}' - link = await self._post_to_hastebin(string) + link = await self.online.hastebin(string) await message.edit( content=f":x: Content too long. {link}", embed=None) @@ -476,7 +465,7 @@ class Developer(commands.Cog): if (len(result[1]) >= 1024): stdout = result[0].decode('utf-8') string = string + f'[[STDERR]]\n{stdout}' - link = await self._post_to_hastebin(string) + link = await self.online.hastebin(string) await message.edit( content=f":x: Content too long. {link}", embed=None) diff --git a/extensions/search.py b/extensions/search.py index 3f023d2..bb36283 100644 --- a/extensions/search.py +++ b/extensions/search.py @@ -67,7 +67,7 @@ class Search(commands.Cog): ) # 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 category: diff --git a/extensions/utils/online.py b/extensions/utils/online.py new file mode 100644 index 0000000..a5edb2e --- /dev/null +++ b/extensions/utils/online.py @@ -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) diff --git a/main.py b/main.py index 557234c..b95c796 100644 --- a/main.py +++ b/main.py @@ -24,7 +24,7 @@ class Bot(commands.Bot): """Initializes the main parts of the bot.""" # Logging - print('Performing initialization...\n') + print('Initializing...\n') # Initializes parent class super().__init__(self._get_prefix_new, **options) @@ -44,31 +44,10 @@ class Bot(commands.Bot): self.instances = f.read().split('\n') # Logging - print('Initialization complete.\n\n') def _init_extensions(self): """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 for ext in os.listdir('extensions/utils'): if ext.endswith('.py'): @@ -79,6 +58,26 @@ class Bot(commands.Bot): 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) + + # 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): """More flexible check for prefix.""" @@ -95,6 +94,8 @@ class Bot(commands.Bot): async def on_ready(self): """Initializes the main portion of the bot once it has connected.""" + print('Connected.\n') + # Prerequisites if not hasattr(self, 'request'): self.request = aiohttp.ClientSession() @@ -108,8 +109,10 @@ class Bot(commands.Bot): if self.extensions_list == []: self._init_extensions() + print('Initialized.\n') + # Logging - msg = "CONNECTED!\n" + msg = "ALL ENGINES GO!\n" msg += "-----------------------------\n" msg += f"ACCOUNT: {bot.user}\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. elif isinstance(error, commands.CommandInvokeError): + # Prerequisites - error = error.original - _traceback = traceback.format_tb(error.__traceback__) - _traceback = ''.join(_traceback) + original_error = error.original + traceback_orig = traceback.format_tb(original_error.__traceback__) + traceback_orig = ''.join(traceback_orig) appinfo = await bot.application_info() + original_exc = traceback.format_exception( + type(original_error), original_error, original_error.__traceback__) + print(original_exc) # 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 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, description=( # TODO Change if has logging "This is (probably) a bug. This has not been automatically " @@ -187,25 +206,32 @@ async def on_command_error(ctx, error): trace_content = ( "```py\n\nTraceback (most recent call last):" "\n{}{}: {}```").format( - _traceback, - type(error).__name__, - error) + traceback_orig, + type(original_error).__name__, + original_error) # Adds Traceback error_embed.add_field( - name="`{}` in command `{}`".format( - type(error).__name__, ctx.command.qualified_name), + name=( + f"`{type(original_error).__name__}` in " + f"command `{ctx.command.qualified_name}`" + ), value=(trace_content[:1018] + '...```') if len(trace_content) > 1024 - else trace_content) + else trace_content + ) # Sending await ctx.send(embed_fallback, embed=error_embed) # If anything else goes wrong, just go ahead and send it in chat. 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) - # NOTE Bot Entry Point # Starts the bot +print("Connecting...\n") bot.run(bot.config['TOKEN'])