New get_webhook and logging features
This commit is contained in:
parent
7ae19ef8a6
commit
a824c068e7
|
@ -19,6 +19,8 @@ class Search(commands.Cog):
|
||||||
|
|
||||||
# Main Stuff
|
# Main Stuff
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.info = bot.logging.info
|
||||||
|
self.warn = bot.logging.warn
|
||||||
self.request = bot.request
|
self.request = bot.request
|
||||||
self.instances = bot.instances
|
self.instances = bot.instances
|
||||||
self.emoji = "\U0001F50D"
|
self.emoji = "\U0001F50D"
|
||||||
|
@ -57,7 +59,6 @@ class Search(commands.Cog):
|
||||||
with open('searxes.txt') as f:
|
with open('searxes.txt') as f:
|
||||||
self.instances = f.read().split('\n')
|
self.instances = f.read().split('\n')
|
||||||
instance = random.sample(self.instances, k=1)[0]
|
instance = random.sample(self.instances, k=1)[0]
|
||||||
print(f"Attempting to use {instance}")
|
|
||||||
|
|
||||||
# Error Template
|
# Error Template
|
||||||
error_msg = (
|
error_msg = (
|
||||||
|
@ -81,9 +82,6 @@ class Search(commands.Cog):
|
||||||
# Figure out engines for different categories to get decent results.
|
# Figure out engines for different categories to get decent results.
|
||||||
if category == 'videos':
|
if category == 'videos':
|
||||||
call += '&engines=bing+videos,google+videos'
|
call += '&engines=bing+videos,google+videos'
|
||||||
|
|
||||||
print(call)
|
|
||||||
|
|
||||||
# Make said API call
|
# Make said API call
|
||||||
try:
|
try:
|
||||||
async with self.request.get(call) as resp:
|
async with self.request.get(call) as resp:
|
||||||
|
@ -121,17 +119,21 @@ class Search(commands.Cog):
|
||||||
# Instance Info
|
# Instance Info
|
||||||
msg += f"\n\n_Results retrieved from instance `{instance}`._"
|
msg += f"\n\n_Results retrieved from instance `{instance}`._"
|
||||||
|
|
||||||
|
return msg
|
||||||
|
|
||||||
# Reached if error with returned results
|
# Reached if error with returned results
|
||||||
except (KeyError, IndexError) as e:
|
except (KeyError, IndexError) as e:
|
||||||
# Logging
|
# Logging
|
||||||
print(f"{e} with instance {instance}, trying again.")
|
self.warn(
|
||||||
|
f"A user encountered a(n) `{e}` with <{instance}> when searching for `{query}`. "
|
||||||
|
"Consider removing it or looking into it.",
|
||||||
|
name="Failed Instance"
|
||||||
|
)
|
||||||
|
|
||||||
self.instances.remove(instance) # Weed the instance out
|
self.instances.remove(instance) # Weed the instance out
|
||||||
# Recurse until good response
|
# Recurse until good response
|
||||||
return await self._search_logic(query, is_nsfw)
|
return await self._search_logic(query, is_nsfw)
|
||||||
|
|
||||||
return msg
|
|
||||||
|
|
||||||
async def _instance_check(self, instance, info):
|
async def _instance_check(self, instance, info):
|
||||||
"""Checks the quality of an instance."""
|
"""Checks the quality of an instance."""
|
||||||
|
|
||||||
|
@ -172,84 +174,94 @@ class Search(commands.Cog):
|
||||||
async def search(self, ctx, *, query: str):
|
async def search(self, ctx, *, query: str):
|
||||||
"""Search online for general results."""
|
"""Search online for general results."""
|
||||||
|
|
||||||
# Logging
|
|
||||||
print(f"\n\nNEW CALL: {ctx.author} from {ctx.guild}.\n")
|
|
||||||
|
|
||||||
# Handling
|
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
msg = await self._search_logic(query, ctx.channel.is_nsfw())
|
msg = await self._search_logic(query, ctx.channel.is_nsfw())
|
||||||
|
await self.info(
|
||||||
|
content=f"**{ctx.author}** searched for `{query}` in \"{ctx.guild}\" and got this:"
|
||||||
|
f"\n\n{msg}",
|
||||||
|
name="Search Results"
|
||||||
|
)
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
|
|
||||||
@commands.command(aliases=['video'])
|
@commands.command(aliases=['video'])
|
||||||
async def videos(self, ctx, *, query: str):
|
async def videos(self, ctx, *, query: str):
|
||||||
"""Search online for videos."""
|
"""Search online for videos."""
|
||||||
|
|
||||||
# Logging
|
|
||||||
print(f"\n\nNEW VIDEO CALL: {ctx.author} from {ctx.guild}.\n")
|
|
||||||
|
|
||||||
# Handling
|
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'videos')
|
msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'videos')
|
||||||
|
await self.info(
|
||||||
|
content=f"**{ctx.author}** searched for `{query}` videos in \"{ctx.guild}\" and got this:"
|
||||||
|
f"\n\n{msg}",
|
||||||
|
name="Search Results"
|
||||||
|
)
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def music(self, ctx, *, query: str):
|
async def music(self, ctx, *, query: str):
|
||||||
"""Search online for music."""
|
"""Search online for music."""
|
||||||
|
|
||||||
# Logging
|
|
||||||
print(f"\n\nNEW MUSIC CALL: {ctx.author} from {ctx.guild}.\n")
|
|
||||||
|
|
||||||
# Handling
|
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'music')
|
msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'music')
|
||||||
|
await self.info(
|
||||||
|
content=f"**{ctx.author}** searched for `{query}` music in \"{ctx.guild}\" and got this:"
|
||||||
|
f"\n\n{msg}",
|
||||||
|
name="Search Results"
|
||||||
|
)
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
|
|
||||||
@commands.command(aliases=['file'])
|
@commands.command(aliases=['file'])
|
||||||
async def files(self, ctx, *, query: str):
|
async def files(self, ctx, *, query: str):
|
||||||
"""Search online for files."""
|
"""Search online for files."""
|
||||||
|
|
||||||
# Logging
|
|
||||||
print(f"\n\nNEW FILES CALL: {ctx.author} from {ctx.guild}.\n")
|
|
||||||
|
|
||||||
# Handling
|
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'files')
|
msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'files')
|
||||||
|
await self.info(
|
||||||
|
content=f"**{ctx.author}** searched for `{query}` files in \"{ctx.guild}\" and got this:"
|
||||||
|
f"\n\n{msg}",
|
||||||
|
name="Search Results"
|
||||||
|
)
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
|
|
||||||
@commands.command(aliases=['image'])
|
@commands.command(aliases=['image'])
|
||||||
async def images(self, ctx, *, query: str):
|
async def images(self, ctx, *, query: str):
|
||||||
"""Search online for images."""
|
"""Search online for images."""
|
||||||
|
|
||||||
# Logging
|
|
||||||
print(f"\n\nNEW IMAGES CALL: {ctx.author} from {ctx.guild}.\n")
|
|
||||||
|
|
||||||
# Handling
|
# Handling
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'images')
|
msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'images')
|
||||||
|
await self.info(
|
||||||
|
content=f"**{ctx.author}** searched for `{query}` images in \"{ctx.guild}\" and got this:"
|
||||||
|
f"\n\n{msg}",
|
||||||
|
name="Search Results"
|
||||||
|
)
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def it(self, ctx, *, query: str):
|
async def it(self, ctx, *, query: str):
|
||||||
"""Search online for IT-related information."""
|
"""Search online for IT-related information."""
|
||||||
|
|
||||||
# Logging
|
|
||||||
print(f"\n\nNEW IT CALL: {ctx.author} from {ctx.guild}.\n")
|
|
||||||
|
|
||||||
# Handling
|
# Handling
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'it')
|
msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'it')
|
||||||
|
await self.info(
|
||||||
|
content=f"**{ctx.author}** searched for `{query}` IT in \"{ctx.guild}\" and got this:"
|
||||||
|
f"\n\n{msg}",
|
||||||
|
name="Search Results"
|
||||||
|
)
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
|
|
||||||
@commands.command(aliases=['map'])
|
@commands.command(aliases=['map'])
|
||||||
async def maps(self, ctx, *, query: str):
|
async def maps(self, ctx, *, query: str):
|
||||||
"""Search online for map information."""
|
"""Search online for map information."""
|
||||||
|
|
||||||
# Logging
|
|
||||||
print(f"\n\nNEW MAP CALL: {ctx.author} from {ctx.guild}.\n")
|
|
||||||
|
|
||||||
# Handling
|
# Handling
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'map')
|
msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'map')
|
||||||
|
await self.info(
|
||||||
|
content=f"**{ctx.author}** searched for `{query}` maps in \"{ctx.guild}\" and got this:"
|
||||||
|
f"\n\n{msg}",
|
||||||
|
name="Search Results"
|
||||||
|
)
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
|
@ -287,9 +299,7 @@ class Search(commands.Cog):
|
||||||
|
|
||||||
if isinstance(error, commands.CommandNotFound) or \
|
if isinstance(error, commands.CommandNotFound) or \
|
||||||
isinstance(error, commands.CheckFailure):
|
isinstance(error, commands.CheckFailure):
|
||||||
# Logging
|
|
||||||
print(f"\n\nNEW CALL: {ctx.author} from {ctx.guild}.\n")
|
|
||||||
|
|
||||||
# Handling
|
# Handling
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
# Prepares term
|
# Prepares term
|
||||||
|
@ -297,6 +307,15 @@ class Search(commands.Cog):
|
||||||
term = term.lstrip(' ')
|
term = term.lstrip(' ')
|
||||||
# Does search
|
# Does search
|
||||||
msg = await self._search_logic(term, ctx.channel.is_nsfw())
|
msg = await self._search_logic(term, ctx.channel.is_nsfw())
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
await self.info(
|
||||||
|
content=f"**{ctx.author}** searched for `{term}` in \"{ctx.guild}\" and got this:"
|
||||||
|
f"\n\n{msg}",
|
||||||
|
name="Search Results"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Sends result
|
# Sends result
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,181 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# tacibot logging util
|
||||||
|
# Provides utils for logging via webhooks.
|
||||||
|
|
||||||
|
'''Online File'''
|
||||||
|
|
||||||
|
import discord
|
||||||
|
from discord.ext.commands import Context
|
||||||
|
import traceback
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
class Logging():
|
||||||
|
"""Provides logging utilities for bots."""
|
||||||
|
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
self.request = bot.request
|
||||||
|
self.online = bot.online
|
||||||
|
self.maintenance = bot.maintenance
|
||||||
|
|
||||||
|
# Sets info hook first
|
||||||
|
self.info_hook = self.online.get_webhook(
|
||||||
|
bot.config['INFO_HOOK'] if bot.config['INFO_HOOK']
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
|
||||||
|
# Sets other hooks or defaults them
|
||||||
|
if self.info_hook:
|
||||||
|
self.warn_hook = self.online.get_webhook(
|
||||||
|
bot.config['WARN_HOOK'] if bot.config['WARN_HOOK']
|
||||||
|
else self.info_hook
|
||||||
|
)
|
||||||
|
self.error_hook = self.online.get_webhook(
|
||||||
|
bot.config['ERROR_HOOK'] if bot.config['ERROR_HOOK']
|
||||||
|
else self.info_hook
|
||||||
|
)
|
||||||
|
self.debug_hook = self.online.get_webhook(
|
||||||
|
bot.config['DEBUG_HOOK'] if bot.config['DEBUG_HOOK']
|
||||||
|
else self.info_hook
|
||||||
|
)
|
||||||
|
|
||||||
|
# If no hooks, nothing is there
|
||||||
|
else:
|
||||||
|
self.warn_hook = self.error_hook = self.debug_hook = None
|
||||||
|
|
||||||
|
async def _create_error_embed(self, error: Exception, ctx: Context):
|
||||||
|
"""Creates a new basic error embed."""
|
||||||
|
|
||||||
|
# Prerequisites
|
||||||
|
formatted_tb = traceback.format_tb(error.__traceback__)
|
||||||
|
formatted_tb = ''.join(formatted_tb)
|
||||||
|
original_exc = traceback.format_exception(
|
||||||
|
type(error), error, error.__traceback__)
|
||||||
|
print(original_exc)
|
||||||
|
|
||||||
|
# Hastebins Traceback
|
||||||
|
try:
|
||||||
|
url = await self.online.hastebin(
|
||||||
|
''.join(original_exc))
|
||||||
|
except Exception as e:
|
||||||
|
url = None
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
# Embed Building
|
||||||
|
error_embed = discord.Embed(
|
||||||
|
title=(
|
||||||
|
f"{type(error).__name__} "
|
||||||
|
f"{'(Click for Hastebin)' if url else ''}"
|
||||||
|
),
|
||||||
|
url=url if url else None,
|
||||||
|
color=0xFF0000
|
||||||
|
)
|
||||||
|
|
||||||
|
# Formats Traceback
|
||||||
|
trace_content = (
|
||||||
|
"```py\n\nTraceback (most recent call last):"
|
||||||
|
"\n{}{}: {}```").format(
|
||||||
|
formatted_tb,
|
||||||
|
type(error).__name__,
|
||||||
|
error)
|
||||||
|
|
||||||
|
# Adds Traceback
|
||||||
|
error_embed.add_field(
|
||||||
|
name=(
|
||||||
|
f"`{type(error).__name__}` in "
|
||||||
|
f"command `{ctx.command.qualified_name}`"
|
||||||
|
),
|
||||||
|
value=(trace_content[:1018] + '...```')
|
||||||
|
if len(trace_content) > 1024
|
||||||
|
else trace_content
|
||||||
|
)
|
||||||
|
|
||||||
|
# Provides completed embed
|
||||||
|
return error_embed
|
||||||
|
|
||||||
|
async def info(self, content: str,
|
||||||
|
embed: Optional[discord.Embed] = None,
|
||||||
|
name: Optional[str] = None):
|
||||||
|
"""Logs info and sends it to the appropriate places."""
|
||||||
|
|
||||||
|
if self.info_hook:
|
||||||
|
return await self.info_hook.send(
|
||||||
|
content=content,
|
||||||
|
username=f"{self.bot.user.name} - {name if name else 'unknown'}",
|
||||||
|
avatar_url=str(self.bot.user.avatar_url),
|
||||||
|
embed=embed
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
async def warn(self, content: str,
|
||||||
|
embed: Optional[discord.Embed] = None,
|
||||||
|
name: Optional[str] = None):
|
||||||
|
"""Logs warnings and sends them to the appropriate places."""
|
||||||
|
|
||||||
|
if self.warn_hook:
|
||||||
|
return await self.warn_hook.send(
|
||||||
|
content=content,
|
||||||
|
username=f"{self.bot.user.name} - {name if name else 'unknown'}",
|
||||||
|
avatar_url=str(self.bot.user.avatar_url),
|
||||||
|
embed=embed
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
async def error(self, error: Exception, ctx: Context, name: Optional[str]):
|
||||||
|
"""Logs errors and sends them to the appropriate places."""
|
||||||
|
|
||||||
|
# Prerequisites
|
||||||
|
error_embed = await self._create_error_embed(error, ctx)
|
||||||
|
|
||||||
|
# Log and say so
|
||||||
|
if self.error_hook:
|
||||||
|
|
||||||
|
# Log
|
||||||
|
fallback = (
|
||||||
|
f"**{ctx.author}** encountered a(n) "
|
||||||
|
f"`{type(error).__name__}` when attempting to use "
|
||||||
|
f"`{ctx.command}`."
|
||||||
|
)
|
||||||
|
await self.error_hook.send(
|
||||||
|
content=fallback,
|
||||||
|
username=f"{self.bot.user.name} - {name if name else 'unknown'}",
|
||||||
|
avatar_url=str(self.bot.user.avatar_url),
|
||||||
|
embed=error_embed
|
||||||
|
)
|
||||||
|
|
||||||
|
# Say so
|
||||||
|
is_reported = "has been automatically reported, but"
|
||||||
|
|
||||||
|
# Say hasn't been logged
|
||||||
|
else:
|
||||||
|
is_reported = "has not been automatically reported, so"
|
||||||
|
|
||||||
|
# Added reported info and return
|
||||||
|
error_embed.description = (
|
||||||
|
f"This is (probably) a bug. This {is_reported} "
|
||||||
|
f"please give **{self.bot.appinfo.owner}** a heads-up in DMs."
|
||||||
|
)
|
||||||
|
return error_embed
|
||||||
|
|
||||||
|
async def debug(self, content: str,
|
||||||
|
embed: Optional[discord.Embed] = None,
|
||||||
|
name: Optional[str] = None):
|
||||||
|
"""Logs warnings and sends them to the appropriate places."""
|
||||||
|
|
||||||
|
if self.debug_hook and self.maintenance:
|
||||||
|
return await self.debug_hook.send(
|
||||||
|
content=content,
|
||||||
|
username=f"{self.bot.user.name} - {name if name else 'unknown'}",
|
||||||
|
avatar_url=str(self.bot.user.avatar_url),
|
||||||
|
embed=embed
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
bot.logging = Logging(bot)
|
|
@ -5,7 +5,12 @@
|
||||||
|
|
||||||
'''Online File'''
|
'''Online File'''
|
||||||
|
|
||||||
|
import discord
|
||||||
|
|
||||||
|
|
||||||
class Online():
|
class Online():
|
||||||
|
"""Provides various online utilities for your bot."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.request = bot.request
|
self.request = bot.request
|
||||||
|
@ -18,11 +23,16 @@ class Online():
|
||||||
async with self.request.post(url=url, data=data) as haste_response:
|
async with self.request.post(url=url, data=data) as haste_response:
|
||||||
haste_key = (await haste_response.json())['key']
|
haste_key = (await haste_response.json())['key']
|
||||||
haste_url = f"http://hastebin.com/{haste_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
|
return haste_url
|
||||||
|
|
||||||
|
def get_webhook(self, url: str):
|
||||||
|
"""Easily gets a webhook from a url."""
|
||||||
|
|
||||||
|
return discord.Webhook.from_url(
|
||||||
|
url,
|
||||||
|
adapter=discord.AsyncWebhookAdapter(self.request)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.online = Online(bot)
|
bot.online = Online(bot)
|
||||||
|
|
66
main.py
66
main.py
|
@ -14,18 +14,15 @@ import json
|
||||||
import os
|
import os
|
||||||
import asyncio
|
import asyncio
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
import logging
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
|
||||||
class Bot(commands.Bot):
|
class Bot(commands.Bot):
|
||||||
"""Custom Bot Class that subclasses the commands.ext one"""
|
"""Custom Bot Class that subclasses the commands.ext one"""
|
||||||
|
|
||||||
def __init__(self, **options):
|
def __init__(self, **options):
|
||||||
"""Initializes the main parts of the bot."""
|
"""Initializes the main parts of the bot."""
|
||||||
|
|
||||||
# Logging
|
|
||||||
print('Initializing...\n')
|
|
||||||
|
|
||||||
# Initializes parent class
|
# Initializes parent class
|
||||||
super().__init__(self._get_prefix_new, **options)
|
super().__init__(self._get_prefix_new, **options)
|
||||||
|
|
||||||
|
@ -43,8 +40,6 @@ class Bot(commands.Bot):
|
||||||
with open('searxes.txt') as f:
|
with open('searxes.txt') as f:
|
||||||
self.instances = f.read().split('\n')
|
self.instances = f.read().split('\n')
|
||||||
|
|
||||||
# Logging
|
|
||||||
|
|
||||||
def _init_extensions(self):
|
def _init_extensions(self):
|
||||||
"""Initializes extensions."""
|
"""Initializes extensions."""
|
||||||
|
|
||||||
|
@ -163,73 +158,22 @@ async def on_command_error(ctx, error):
|
||||||
|
|
||||||
# Lets other cogs handle CommandNotFound.
|
# Lets other cogs handle CommandNotFound.
|
||||||
# Change this if you want command not found handling
|
# Change this if you want command not found handling
|
||||||
if isinstance(error, commands.CommandNotFound):
|
if isinstance(error, commands.CommandNotFound)or isinstance(error, commands.CheckFailure):
|
||||||
return
|
return
|
||||||
|
|
||||||
# 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
|
||||||
original_error = error.original
|
embed_fallback = f"**An error occured: {type(error).__name__}. Please contact {bot.appinfo.owner}.**"
|
||||||
traceback_orig = traceback.format_tb(original_error.__traceback__)
|
error_embed = await bot.logging.error(error, ctx, ctx.command.cog.__name__)
|
||||||
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(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(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 "
|
|
||||||
f"reported, so please give **{appinfo.owner}** a heads-up in DMs.")
|
|
||||||
)
|
|
||||||
|
|
||||||
# Formats Traceback
|
|
||||||
trace_content = (
|
|
||||||
"```py\n\nTraceback (most recent call last):"
|
|
||||||
"\n{}{}: {}```").format(
|
|
||||||
traceback_orig,
|
|
||||||
type(original_error).__name__,
|
|
||||||
original_error)
|
|
||||||
|
|
||||||
# Adds Traceback
|
|
||||||
error_embed.add_field(
|
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
# 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
|
await bot.logging.error(error, ctx, ctx.command.cog.__name__)
|
||||||
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
|
||||||
|
|
Loading…
Reference in New Issue