1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-12-17 23:24:20 +00:00

Add error handling

This commit is contained in:
Steffo 2019-08-29 13:29:59 +02:00
parent 4777f93461
commit 3aee0452d7
8 changed files with 80 additions and 19 deletions

View file

@ -18,3 +18,4 @@ flask>=1.0.3
markdown2>=2.3.8 markdown2>=2.3.8
mcstatus>=2.2.1 mcstatus>=2.2.1
sortedcontainers>=2.1.0 sortedcontainers>=2.1.0
sentry-sdk>=0.11.1

View file

@ -1,5 +1,6 @@
import discord import discord
import typing import typing
import sentry_sdk
import logging as _logging import logging as _logging
from .generic import GenericBot from .generic import GenericBot
from ..utils import * from ..utils import *
@ -113,9 +114,17 @@ class DiscordBot(GenericBot):
except KeyError: except KeyError:
# Skip the message # Skip the message
return return
# Prepare data
data = self._Data(interface=command.interface, message=message)
# Call the command # Call the command
with message.channel.typing(): with message.channel.typing():
await command.run(CommandArgs(parameters), self._Data(interface=command.interface, message=message)) try:
await command.run(CommandArgs(parameters), data=data)
except Exception as e:
sentry_sdk.capture_exception(e)
error_message = f"⛔️ {e.__class__.__name__}\n"
error_message += '\n'.join(e.args)
await data.reply(error_message)
async def on_ready(cli): async def on_ready(cli):
log.debug("Connection successful, client is ready") log.debug("Connection successful, client is ready")
@ -189,9 +198,11 @@ class DiscordBot(GenericBot):
discord_config: DiscordConfig, discord_config: DiscordConfig,
royalnet_config: typing.Optional[RoyalnetConfig] = None, royalnet_config: typing.Optional[RoyalnetConfig] = None,
database_config: typing.Optional[DatabaseConfig] = None, database_config: typing.Optional[DatabaseConfig] = None,
sentry_dsn: typing.Optional[str] = None,
commands: typing.List[typing.Type[Command]] = None): commands: typing.List[typing.Type[Command]] = None):
super().__init__(royalnet_config=royalnet_config, super().__init__(royalnet_config=royalnet_config,
database_config=database_config, database_config=database_config,
sentry_dsn=sentry_dsn,
commands=commands) commands=commands)
self._discord_config = discord_config self._discord_config = discord_config
self._init_client() self._init_client()

View file

@ -2,6 +2,7 @@ import sys
import typing import typing
import asyncio import asyncio
import logging import logging
import sentry_sdk
from ..utils import * from ..utils import *
from ..network import * from ..network import *
from ..database import * from ..database import *
@ -124,11 +125,18 @@ class GenericBot:
royalnet_config: typing.Optional[RoyalnetConfig] = None, royalnet_config: typing.Optional[RoyalnetConfig] = None,
database_config: typing.Optional[DatabaseConfig] = None, database_config: typing.Optional[DatabaseConfig] = None,
commands: typing.List[typing.Type[Command]] = None, commands: typing.List[typing.Type[Command]] = None,
sentry_dsn: typing.Optional[str] = None,
loop: asyncio.AbstractEventLoop = None): loop: asyncio.AbstractEventLoop = None):
if loop is None: if loop is None:
self.loop = asyncio.get_event_loop() self.loop = asyncio.get_event_loop()
else: else:
self.loop = loop self.loop = loop
if sentry_dsn:
log.debug("Sentry int")
self.sentry = sentry_sdk.init(sentry_dsn)
else:
log.debug("Sentry integration not enabled")
try:
if database_config is None: if database_config is None:
self.alchemy = None self.alchemy = None
self.master_table = None self.master_table = None
@ -143,6 +151,8 @@ class GenericBot:
self.network = None self.network = None
else: else:
self._init_royalnet(royalnet_config=royalnet_config) self._init_royalnet(royalnet_config=royalnet_config)
except Exception as e:
sentry_sdk.capture_exception(e)
async def run(self): async def run(self):
"""A blocking coroutine that should make the bot start listening to commands and requests.""" """A blocking coroutine that should make the bot start listening to commands and requests."""

View file

@ -1,6 +1,8 @@
import telegram import telegram
import telegram.utils.request import telegram.utils.request
import typing import typing
import asyncio
import sentry_sdk
import logging as _logging import logging as _logging
from .generic import GenericBot from .generic import GenericBot
from ..utils import * from ..utils import *
@ -74,9 +76,11 @@ class TelegramBot(GenericBot):
telegram_config: TelegramConfig, telegram_config: TelegramConfig,
royalnet_config: typing.Optional[RoyalnetConfig] = None, royalnet_config: typing.Optional[RoyalnetConfig] = None,
database_config: typing.Optional[DatabaseConfig] = None, database_config: typing.Optional[DatabaseConfig] = None,
sentry_dsn: typing.Optional[str] = None,
commands: typing.List[typing.Type[Command]] = None): commands: typing.List[typing.Type[Command]] = None):
super().__init__(royalnet_config=royalnet_config, super().__init__(royalnet_config=royalnet_config,
database_config=database_config, database_config=database_config,
sentry_dsn=sentry_dsn,
commands=commands) commands=commands)
self._telegram_config = telegram_config self._telegram_config = telegram_config
self._init_client() self._init_client()
@ -107,16 +111,27 @@ class TelegramBot(GenericBot):
except KeyError: except KeyError:
# Skip the message # Skip the message
return return
# Prepare data
data = self._Data(interface=command.interface, update=update)
# Run the command # Run the command
await command.run(CommandArgs(parameters), self._Data(interface=command.interface, update=update)) try:
await command.run(CommandArgs(parameters), data)
except Exception as e:
sentry_sdk.capture_exception(e)
error_message = f"⛔️ [b]{e.__class__.__name__}[/b]\n"
error_message += '\n'.join(e.args)
await data.reply(error_message)
async def run(self): async def run(self):
while True: while True:
# Get the latest 100 updates # Get the latest 100 updates
try: try:
last_updates: typing.List[telegram.Update] = await asyncify(self.client.get_updates, offset=self._offset, timeout=60) last_updates: typing.List[telegram.Update] = await asyncify(self.client.get_updates,
except telegram.error.TimedOut: offset=self._offset,
continue timeout=60)
except telegram.error.TelegramError as error:
sentry_sdk.capture_exception(error)
await asyncio.sleep(5)
# Handle updates # Handle updates
for update in last_updates: for update in last_updates:
# noinspection PyAsyncCall # noinspection PyAsyncCall

View file

@ -0,0 +1,3 @@
from .debug_error import DebugErrorCommand
__all__ = ["DebugErrorCommand"]

View file

@ -0,0 +1,13 @@
import typing
from ..command import Command
from ..commandargs import CommandArgs
from ..commanddata import CommandData
class DebugErrorCommand(Command):
name: str = "debug_error"
description: str = "Causa un'eccezione nel bot."
async def run(self, args: CommandArgs, data: CommandData) -> None:
raise Exception("debug_error command was called")

View file

@ -3,8 +3,10 @@
import os import os
import asyncio import asyncio
import logging import logging
import sentry_sdk
from royalnet.bots import DiscordBot, DiscordConfig, TelegramBot, TelegramConfig from royalnet.bots import DiscordBot, DiscordConfig, TelegramBot, TelegramConfig
from royalnet.commands.royalgames import * from royalnet.commands.royalgames import *
from royalnet.commands.debug import *
from royalnet.network import RoyalnetServer, RoyalnetConfig from royalnet.network import RoyalnetServer, RoyalnetConfig
from royalnet.database import DatabaseConfig from royalnet.database import DatabaseConfig
from royalnet.database.tables import Royal, Telegram, Discord from royalnet.database.tables import Royal, Telegram, Discord
@ -38,9 +40,12 @@ commands = [
DndspellCommand DndspellCommand
] ]
sentry_dsn = os.environ.get("SENTRY_DSN")
# noinspection PyUnreachableCode # noinspection PyUnreachableCode
if __debug__: if __debug__:
log.setLevel(logging.DEBUG) log.setLevel(logging.DEBUG)
commands = [*commands, DebugErrorCommand]
else: else:
log.setLevel(logging.INFO) log.setLevel(logging.INFO)
@ -54,10 +59,12 @@ print("Starting bots...")
ds_bot = DiscordBot(discord_config=DiscordConfig(os.environ["DS_AK"]), ds_bot = DiscordBot(discord_config=DiscordConfig(os.environ["DS_AK"]),
royalnet_config=RoyalnetConfig(f"ws://{address}:{port}", os.environ["MASTER_KEY"]), royalnet_config=RoyalnetConfig(f"ws://{address}:{port}", os.environ["MASTER_KEY"]),
database_config=DatabaseConfig(os.environ["DB_PATH"], Royal, Discord, "discord_id"), database_config=DatabaseConfig(os.environ["DB_PATH"], Royal, Discord, "discord_id"),
sentry_dsn=sentry_dsn,
commands=commands) commands=commands)
tg_bot = TelegramBot(telegram_config=TelegramConfig(os.environ["TG_AK"]), tg_bot = TelegramBot(telegram_config=TelegramConfig(os.environ["TG_AK"]),
royalnet_config=RoyalnetConfig(f"ws://{address}:{port}", os.environ["MASTER_KEY"]), royalnet_config=RoyalnetConfig(f"ws://{address}:{port}", os.environ["MASTER_KEY"]),
database_config=DatabaseConfig(os.environ["DB_PATH"], Royal, Telegram, "tg_id"), database_config=DatabaseConfig(os.environ["DB_PATH"], Royal, Telegram, "tg_id"),
sentry_dsn=sentry_dsn,
commands=commands) commands=commands)
loop.create_task(tg_bot.run()) loop.create_task(tg_bot.run())
loop.create_task(ds_bot.run()) loop.create_task(ds_bot.run())

View file

@ -29,7 +29,8 @@ setuptools.setup(
"flask>=1.0.3", "flask>=1.0.3",
"markdown2>=2.3.8", "markdown2>=2.3.8",
"mcstatus>=2.2.1", "mcstatus>=2.2.1",
"sortedcontainers>=2.1.0"], "sortedcontainers>=2.1.0",
"sentry-sdk>=0.11.1"],
python_requires=">=3.7", python_requires=">=3.7",
classifiers=[ classifiers=[
"Development Status :: 3 - Alpha", "Development Status :: 3 - Alpha",