diff --git a/poetry.lock b/poetry.lock index a33e322d..2a3256db 100644 --- a/poetry.lock +++ b/poetry.lock @@ -389,6 +389,34 @@ python-versions = ">=3.5, <4" [package.dependencies] pyasn1 = ">=0.1.3" +[[package]] +name = "sentry-sdk" +version = "1.0.0" +description = "Python client for Sentry (https://sentry.io)" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +certifi = "*" +urllib3 = ">=1.10.0" + +[package.extras] +aiohttp = ["aiohttp (>=3.5)"] +beam = ["apache-beam (>=2.12)"] +bottle = ["bottle (>=0.12.13)"] +celery = ["celery (>=3)"] +chalice = ["chalice (>=1.16.0)"] +django = ["django (>=1.8)"] +falcon = ["falcon (>=1.4)"] +flask = ["flask (>=0.11)", "blinker (>=1.1)"] +pure_eval = ["pure-eval", "executing", "asttokens"] +pyspark = ["pyspark (>=2.4.4)"] +rq = ["rq (>=0.6)"] +sanic = ["sanic (>=0.8)"] +sqlalchemy = ["sqlalchemy (>=1.2)"] +tornado = ["tornado (>=5)"] + [[package]] name = "six" version = "1.15.0" @@ -540,7 +568,7 @@ multidict = ">=4.0" [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "f99a271cf9b7884b16eb47476beb88b2a20206deafbbf8d04a92885d289d1430" +content-hash = "2a7daab4f6b74600f4abd0696cca24d628d9c7bcc8eac455008cc547fdc126ab" [metadata.files] aiohttp = [ @@ -948,6 +976,10 @@ rsa = [ {file = "rsa-4.7.2-py3-none-any.whl", hash = "sha256:78f9a9bf4e7be0c5ded4583326e7461e3a3c5aae24073648b4bdfa797d78c9d2"}, {file = "rsa-4.7.2.tar.gz", hash = "sha256:9d689e6ca1b3038bc82bf8d23e944b6b6037bc02301a574935b2dd946e0353b9"}, ] +sentry-sdk = [ + {file = "sentry-sdk-1.0.0.tar.gz", hash = "sha256:71de00c9711926816f750bc0f57ef2abbcb1bfbdf5378c601df7ec978f44857a"}, + {file = "sentry_sdk-1.0.0-py2.py3-none-any.whl", hash = "sha256:9221e985f425913204989d0e0e1cbb719e8b7fa10540f1bc509f660c06a34e66"}, +] six = [ {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, diff --git a/pyproject.toml b/pyproject.toml index 8f022b0c..43072fb2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,7 @@ colour = "^0.1.5" royalspells = "^3.2" async-timeout = "^3.0.1" royalnet-discordpy = "~0.5.8" +sentry-sdk = "^1.0.0" [tool.poetry.dev-dependencies] diff --git a/royalpack/__main__.py b/royalpack/__main__.py index f62b35f9..6f58c501 100644 --- a/royalpack/__main__.py +++ b/royalpack/__main__.py @@ -1,4 +1,5 @@ import discord +import pkg_resources import royalnet.engineer as engi import royalnet.scrolls as sc import royalnet_telethon as rt @@ -6,13 +7,36 @@ import royalnet_discordpy as rd import pathlib import re import coloredlogs +import sentry_sdk +import sentry_sdk.integrations.atexit +import sentry_sdk.integrations.dedupe +import sentry_sdk.integrations.modules +import sentry_sdk.integrations.threading +import logging from . import commands from .database import engine, base -coloredlogs.install(level="DEBUG", isatty=True) +coloredlogs.install(level="DEBUG" if __debug__ else "INFO", isatty=True) config = sc.Scroll.from_file(namespace="ROYALPACK", file_path=pathlib.Path("royalpack.cfg.toml")) +if dsn := config.get("sentry.dsn", None): + logging.info("Enabling Sentry...") + sentry_sdk.init( + dsn=dsn, + debug=__debug__, + release=pkg_resources.get_distribution("royalpack").version, + environment="Development" if __debug__ else "Production", + default_integrations=False, + integrations=[ + sentry_sdk.integrations.atexit.AtexitIntegration(), + sentry_sdk.integrations.dedupe.DedupeIntegration(), + sentry_sdk.integrations.modules.ModulesIntegration(), + sentry_sdk.integrations.threading.ThreadingIntegration(), + ], + traces_sample_rate=1.0 + ) + engine_ = engine.lazy_engine.evaluate() base.Base.metadata.create_all(engine_) diff --git a/royalpack/bolts/__init__.py b/royalpack/bolts/__init__.py index 59e69117..0bdcf3fe 100644 --- a/royalpack/bolts/__init__.py +++ b/royalpack/bolts/__init__.py @@ -1,2 +1,3 @@ from .login import * from .target import * +from .sentry import * diff --git a/royalpack/bolts/sentry.py b/royalpack/bolts/sentry.py new file mode 100644 index 00000000..afabf7fd --- /dev/null +++ b/royalpack/bolts/sentry.py @@ -0,0 +1,29 @@ +""" + +""" + +from __future__ import annotations + +import functools +import logging +import sentry_sdk + +log = logging.getLogger(__name__) + + +def capture_errors(f): + @functools.wraps(f) + async def decorated(**f_kwargs): + try: + return await f(**f_kwargs) + except Exception as e: + log.error(f"Captured error: {e!r}") + if sentry_sdk.Hub.current is not None: + sentry_sdk.capture_exception(error=e) + + return decorated + + +__all__ = ( + "capture_errors", +) diff --git a/royalpack/commands/ahnonlosoio.py b/royalpack/commands/ahnonlosoio.py index a25af863..a7e6260b 100644 --- a/royalpack/commands/ahnonlosoio.py +++ b/royalpack/commands/ahnonlosoio.py @@ -1,6 +1,8 @@ import royalnet.engineer as engi +import royalpack.bolts as rb +@rb.capture_errors @engi.TeleportingConversation async def ahnonlosoio(*, _msg: engi.Message, **__): """ diff --git a/royalpack/commands/answer.py b/royalpack/commands/answer.py index d55c89d6..eadaa619 100644 --- a/royalpack/commands/answer.py +++ b/royalpack/commands/answer.py @@ -1,5 +1,5 @@ import royalnet.engineer as engi -import royalnet.engineer.conversation as c +import royalpack.bolts as rb import datetime import random @@ -73,6 +73,7 @@ ANSWERS = [ ] +@rb.capture_errors @engi.TeleportingConversation async def answer(*, _msg: engi.Message, **__): """ diff --git a/royalpack/commands/cat.py b/royalpack/commands/cat.py index e48bfa16..b353dfa4 100644 --- a/royalpack/commands/cat.py +++ b/royalpack/commands/cat.py @@ -3,10 +3,12 @@ import logging import aiohttp import royalnet.engineer as engi +import royalpack.bolts as rb log = logging.getLogger(__name__) +@rb.capture_errors @engi.TeleportingConversation async def cat(*, _msg: engi.Message, **__): """ diff --git a/royalpack/commands/ciaoruozi.py b/royalpack/commands/ciaoruozi.py index 6e6ffba1..69614977 100644 --- a/royalpack/commands/ciaoruozi.py +++ b/royalpack/commands/ciaoruozi.py @@ -1,9 +1,10 @@ import royalnet.engineer as engi -import royalnet.engineer.conversation as c import royalnet_telethon import royalnet_telethon.bullet.contents +import royalpack.bolts as rb +@rb.capture_errors @engi.TeleportingConversation async def ciaoruozi(*, _msg: engi.Message, _imp, **__): """ diff --git a/royalpack/commands/color.py b/royalpack/commands/color.py index f03cde43..668ba5a8 100644 --- a/royalpack/commands/color.py +++ b/royalpack/commands/color.py @@ -1,6 +1,8 @@ import royalnet.engineer as engi +import royalpack.bolts as rb +@rb.capture_errors @engi.TeleportingConversation async def color(*, _msg: engi.Message, **__): """ diff --git a/royalpack/commands/cv.py b/royalpack/commands/cv.py index c03338df..0fc27061 100644 --- a/royalpack/commands/cv.py +++ b/royalpack/commands/cv.py @@ -1,11 +1,13 @@ import royalnet.royaltyping as t import royalnet.engineer as engi import royalnet_discordpy as rd +import royalpack.bolts as rb import discord import discord.channel import itertools +@rb.capture_errors @engi.TeleportingConversation async def cv(*, _msg: engi.Message, _pda: engi.PDA, **__): """ diff --git a/royalpack/commands/dog.py b/royalpack/commands/dog.py index 9bbe7637..a612e1c8 100644 --- a/royalpack/commands/dog.py +++ b/royalpack/commands/dog.py @@ -2,8 +2,10 @@ import io import aiohttp import royalnet.engineer as engi +import royalpack.bolts as rb +@rb.capture_errors @engi.TeleportingConversation async def dog_any(*, _msg: engi.Message, **__): """ diff --git a/royalpack/commands/emojify.py b/royalpack/commands/emojify.py index 2d053507..accef2ee 100644 --- a/royalpack/commands/emojify.py +++ b/royalpack/commands/emojify.py @@ -1,4 +1,5 @@ import royalnet.engineer as engi +import royalpack.bolts as rb import random @@ -79,6 +80,7 @@ _emojis = { } +@rb.capture_errors @engi.TeleportingConversation async def emojify(*, _msg: engi.Message, message: str, **__): """ diff --git a/royalpack/commands/fiorygi.py b/royalpack/commands/fiorygi.py index 954373b7..0ddb06af 100644 --- a/royalpack/commands/fiorygi.py +++ b/royalpack/commands/fiorygi.py @@ -7,6 +7,7 @@ import functools import arrow +@rb.capture_errors @engi.use_database(db.lazy_session_class) @rb.use_ryglogin(allow_anonymous=False) @engi.TeleportingConversation @@ -18,6 +19,7 @@ async def fiorygi_balance_self(*, _user: db.User, _msg: engi.Message, **__): await _msg.reply(text=f"💰 Attualmente, possiedi \uE01Bƒ {_user.fiorygi}\uE00B.") +@rb.capture_errors @engi.use_database(db.lazy_session_class) @rb.with_target() @engi.TeleportingConversation @@ -51,6 +53,7 @@ def render(transaction: db.Transaction, user: db.User): return " - ".join(row) +@rb.capture_errors @engi.use_database(db.lazy_session_class) @rb.use_ryglogin(allow_anonymous=False) @engi.TeleportingConversation @@ -79,6 +82,7 @@ async def fiorygi_transactions_self(*, _session: db.SessionType, _user: db.User, await _msg.reply(text="\n\n".join(msg)) +@rb.capture_errors @engi.use_database(db.lazy_session_class) @rb.with_target() @engi.TeleportingConversation @@ -107,6 +111,7 @@ async def fiorygi_transactions_other(*, _session: db.SessionType, _target: db.Us await _msg.reply(text="\n\n".join(msg)) +@rb.capture_errors @engi.use_database(db.lazy_session_class) @rb.use_ryglogin(allow_anonymous=False) @rb.with_target() @@ -153,6 +158,7 @@ async def fiorygi_give( await _msg.reply(text=f"💸 Hai trasferito \uE01Bƒ {amount}\uE00B a {_target}.") +@rb.capture_errors @engi.use_database(db.lazy_session_class) @rb.use_ryglogin(allow_anonymous=False) @rb.with_target() @@ -199,6 +205,7 @@ async def fiorygi_magick( await _msg.reply(text=f"🏦 Hai modificato il portafoglio di {_target} di \uE01Bƒ {amount}\uE00B.") +@rb.capture_errors @engi.use_database(db.lazy_session_class) @rb.use_ryglogin(allow_anonymous=False) @engi.TeleportingConversation @@ -251,6 +258,7 @@ async def fiorygi_dig( await _msg.reply(text=f"🏖 Hai trovato un tesoro nascosto dal valore di \uE01Bƒ {treasure.value}\uE00B!") +@rb.capture_errors @engi.use_database(db.lazy_session_class) @rb.use_ryglogin(allow_anonymous=False) @engi.TeleportingConversation diff --git a/royalpack/commands/fortune.py b/royalpack/commands/fortune.py index b7b360e4..6ec54593 100644 --- a/royalpack/commands/fortune.py +++ b/royalpack/commands/fortune.py @@ -1,6 +1,7 @@ import royalnet.engineer as engi import random import datetime +import royalpack.bolts as rb # Tutte le fortunes qui devono essere positive :) @@ -56,6 +57,7 @@ _fortunes = [ ] +@rb.capture_errors @engi.TeleportingConversation async def fortune(*, _msg: engi.Message, **__): """ diff --git a/royalpack/commands/login.py b/royalpack/commands/login.py index ec6b614a..934a9162 100644 --- a/royalpack/commands/login.py +++ b/royalpack/commands/login.py @@ -6,6 +6,7 @@ import royalpack.database as db import royalpack.config as cfg import royalnet_telethon.bullet.contents import royalnet_discordpy +import royalpack.bolts as rb import aiohttp import asyncio import logging @@ -15,9 +16,7 @@ import async_timeout log = logging.getLogger(__name__) -# FIXME: Properly handle errors in this function! - - +@rb.capture_errors @engi.use_database(db.lazy_session_class) @engi.TeleportingConversation async def login(*, _msg: engi.Message, _session: so.Session, _imp, **__): diff --git a/royalpack/commands/man.py b/royalpack/commands/man.py index 3a215dd3..b8475d37 100644 --- a/royalpack/commands/man.py +++ b/royalpack/commands/man.py @@ -1,6 +1,8 @@ import royalnet.engineer as engi +import royalpack.bolts as rb +@rb.capture_errors @engi.TeleportingConversation async def man(*, _msg: engi.Message, _router: engi.Router, commandname: str, **__): """ diff --git a/royalpack/commands/ping.py b/royalpack/commands/ping.py index 0e07ed56..7ed3da7e 100644 --- a/royalpack/commands/ping.py +++ b/royalpack/commands/ping.py @@ -1,6 +1,8 @@ import royalnet.engineer as engi +import royalpack.bolts as rb +@rb.capture_errors @engi.TeleportingConversation async def ping(*, _msg: engi.Message, **__): """ diff --git a/royalpack/commands/pmots.py b/royalpack/commands/pmots.py index f979881b..1cb0a1ff 100644 --- a/royalpack/commands/pmots.py +++ b/royalpack/commands/pmots.py @@ -1,6 +1,8 @@ import royalnet.engineer as engi +import royalpack.bolts as rb +@rb.capture_errors @engi.TeleportingConversation async def pmots(*, _msg: engi.Message, **__): """ diff --git a/royalpack/commands/ship.py b/royalpack/commands/ship.py index 34c63dcc..8ea186f2 100644 --- a/royalpack/commands/ship.py +++ b/royalpack/commands/ship.py @@ -1,11 +1,13 @@ import logging import re +import royalpack.bolts as rb import royalnet.engineer as engi log = logging.getLogger(__name__) +@rb.capture_errors @engi.TeleportingConversation async def ship(*, _msg: engi.Message, first: str, second: str, **__): """ diff --git a/royalpack/commands/smecds.py b/royalpack/commands/smecds.py index e3a0fc45..ef7f975f 100644 --- a/royalpack/commands/smecds.py +++ b/royalpack/commands/smecds.py @@ -1,5 +1,6 @@ import royalnet.engineer as engi import random +import royalpack.bolts as rb _ds_list = ["della secca", "del seccatore", "del secchiello", "del secchio", "del secchione", "del secondino", @@ -54,6 +55,7 @@ _ds_list = ["della secca", "del seccatore", "del secchiello", "del secchio", "de "della Stampante"] +@rb.capture_errors @engi.TeleportingConversation async def smecds(*, _msg: engi.Message, **__): """ diff --git a/royalpack/commands/spell.py b/royalpack/commands/spell.py index 1d60a47d..0a9e13ad 100644 --- a/royalpack/commands/spell.py +++ b/royalpack/commands/spell.py @@ -1,7 +1,9 @@ import royalnet.engineer as engi import royalspells +import royalpack.bolts as rb +@rb.capture_errors @engi.TeleportingConversation async def spell(*, _msg: engi.Message, spellname: str, **__): """ diff --git a/royalpack/commands/version.py b/royalpack/commands/version.py index 876daad8..466cfcd8 100644 --- a/royalpack/commands/version.py +++ b/royalpack/commands/version.py @@ -1,8 +1,10 @@ import royalnet.engineer as engi import royalnet_telethon as rt import pkg_resources +import royalpack.bolts as rb +@rb.capture_errors @engi.TeleportingConversation async def version(*, _imp: engi.PDAImplementation, _msg: engi.Message, **__): """ diff --git a/royalpack/commands/whoami.py b/royalpack/commands/whoami.py index f812b65a..b26b5c89 100644 --- a/royalpack/commands/whoami.py +++ b/royalpack/commands/whoami.py @@ -3,6 +3,7 @@ import royalpack.database as db import royalpack.bolts as rb +@rb.capture_errors @engi.use_database(db.lazy_session_class) @rb.use_ryglogin(allow_anonymous=True) @engi.TeleportingConversation