Skip to content

Instantly share code, notes, and snippets.

@PikalaxALT
Created December 25, 2019 15:47
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PikalaxALT/c2c13a437fbb5387d9c28aeb8a261cd7 to your computer and use it in GitHub Desktop.
Save PikalaxALT/c2c13a437fbb5387d9c28aeb8a261cd7 to your computer and use it in GitHub Desktop.
discord.py bot error handler which bugs the owner with any problems. Good for logging.
import discord
from discord.ext import commands
import aiohttp
import io
import traceback
import config # includes the token
# These exceptions are ignored.
filter_excs = (commands.CommandNotFound, commands.CheckFailure)
# These are exception types you want to handle explicitly.
handle_excs = (commands.UserInputError,)
bot = commands.Bot(command_prefix='!')
async def try_hastebin(content):
"""Upload to Hastebin, if possible."""
payload = content.encode('utf-8')
async with aiohttp.ClientSession(raise_for_status=True) as cs:
async with cs.post('https://hastebin.com/documents', data=payload) as res:
post = await res.json()
uri = post['key']
return f'https://hastebin/{uri}'
async def send_to_owner(content):
"""Send content to owner. If content is small enough, send directly.
Otherwise, try Hastebin first, then upload as a File."""
owner = bot.get_user(bot.owner_id)
if owner is None:
return
if len(content) < 1990:
await owner.send(f'```\ncontent\n```')
else:
try:
await owner.send(await try_hastebin(content))
except aiohttp.ClientResponseError:
await owner.send(file=discord.File(io.StringIO(content), filename='traceback.txt'))
@bot.event
async def on_error(event, *args, **kwargs):
"""Error handler for all events."""
s = traceback.format_exc()
content = f'Ignoring exception in {event}\n{s}'
print(content, file=sys.stderr)
await send_to_owner(content)
async def handle_command_error(ctx: commands.Context, exc: Exception):
"""Handle specific exceptions separately here"""
pass
@bot.event
async def on_command_error(ctx: commands.Context, exc: Exception):
"""Error handler for commands"""
if isinstance(exc, filter_excs):
# These exceptions are ignored completely.
return
if isinstance(exc, handle_excs):
# Explicitly handle these exceptions.
return await handle_command_error(ctx, exc)
# Log the error and bug the owner.
exc = getattr(exc, 'original', exc)
lines = ''.join(traceback.format_exception(exc.__class__, exc, exc.__traceback__))
lines = f'Ignoring exception in command {ctx.command}:\n{lines}'
print(lines)
await send_to_owner(lines)
bot.run(config.token)
@trevorflahardy
Copy link

I would change your send to owner function so it doesn't send him only content

async def send_to_owner(content):
    """Send content to owner. If content is small enough, send directly.
    Otherwise, try Hastebin first, then upload as a File."""
    owner = bot.get_user(bot.owner_id)
    if owner is None:
        return
    if len(content) < 1990:
        await owner.send(f'```python\n{content}\n```')
    else:
        try:
            await owner.send(await try_hastebin(content))
        except aiohttp.ClientResponseError:
            await owner.send(file=discord.File(io.StringIO(content), filename='traceback.txt'))

@Madbrad200
Copy link

return f'https://hastebin/{uri}'

This url doesn't appear to be formatted properly, you want:

return f'https://hastebin.com/{uri}.bash' (.bash might be optional)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment