diff --git a/apps/tgbot/pyproject.toml b/apps/tgbot/pyproject.toml index 97db224..8aaf5f1 100644 --- a/apps/tgbot/pyproject.toml +++ b/apps/tgbot/pyproject.toml @@ -15,6 +15,8 @@ loguru = "^0.5.3" whois-vu = "^0.3.0" tortoise-orm = "^0.16.20" aiomysql = "^0.0.21" +sentry-sdk = "^1.0.0" +aiocontextvars = "^0.2.2" [tool.poetry.dev-dependencies] pytest = "^6.2.2" diff --git a/apps/tgbot/tgbot/bot.py b/apps/tgbot/tgbot/bot.py index 954a8ee..8fc3270 100644 --- a/apps/tgbot/tgbot/bot.py +++ b/apps/tgbot/tgbot/bot.py @@ -1,3 +1,12 @@ +import sentry_sdk +from tgbot import config + +if config.SENTRY_DSN: + + sentry_sdk.init( + dsn=config.SENTRY_DSN, + ) + from asyncio import sleep from aiogram import Bot, Dispatcher, executor @@ -6,9 +15,10 @@ from loguru import logger from tortoise import Tortoise from tortoise.exceptions import DBConnectionError -from . import config, handlers -from .middlewares import (LoggingMiddleware, ThrottlingMiddleware, - UserMiddleware, WriteCommandMetric) +from . import handlers +from .middlewares import ( + LoggingMiddleware, ThrottlingMiddleware, UserMiddleware, WriteCommandMetric +) storage = MemoryStorage() telegram_bot = Bot(token=config.TELEGRAM_BOT_TOKEN) diff --git a/apps/tgbot/tgbot/config.py b/apps/tgbot/tgbot/config.py index 4b82193..94b5b3d 100644 --- a/apps/tgbot/tgbot/config.py +++ b/apps/tgbot/tgbot/config.py @@ -20,3 +20,6 @@ MYSQL_USER = os.getenv("MYSQL_USER") MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD") MYSQL_PORT = os.getenv("MYSQL_PORT", 3306) MYSQL_DATABASE = os.getenv("MYSQL_DATABASE", "unicheckbot") + +# Sentry +SENTRY_DSN = os.getenv("SENTRY_DSN") diff --git a/apps/tgbot/tgbot/handlers/default/start.py b/apps/tgbot/tgbot/handlers/default/start.py index 978636e..eadfe75 100644 --- a/apps/tgbot/tgbot/handlers/default/start.py +++ b/apps/tgbot/tgbot/handlers/default/start.py @@ -36,4 +36,8 @@ start_message = """ @userdata_required @rate_limit async def start_cmd(msg: Message, user: User): - await msg.answer(start_message.replace("%name%", msg.from_user.full_name), parse_mode='markdown', disable_web_page_preview=True) + await msg.answer( + start_message.replace("%name%", msg.from_user.full_name), + parse_mode='markdown', + disable_web_page_preview=True + ) diff --git a/apps/tgbot/tgbot/handlers/default/whois.py b/apps/tgbot/tgbot/handlers/default/whois.py index da3e298..4614d8a 100644 --- a/apps/tgbot/tgbot/handlers/default/whois.py +++ b/apps/tgbot/tgbot/handlers/default/whois.py @@ -4,6 +4,7 @@ from typing import Optional from aiogram.types import Message from whois_vu.api import WhoisSource from whois_vu.errors import IncorrectZone, QueryNotMatchRegexp +from sentry_sdk import capture_exception from whois import parser, whois @@ -72,7 +73,8 @@ def create_whois_message(domain: str) -> str: domain_info = whois_request(domain) except parser.PywhoisError: return f"❗ Домен {domain} свободен или не был найден." - except IncorrectZone: + except IncorrectZone as e: + capture_exception(e) return incorrect_domain.format(domain=domain) except QueryNotMatchRegexp: return incorrect_domain.format(domain=domain) diff --git a/apps/tgbot/tgbot/handlers/helpers.py b/apps/tgbot/tgbot/handlers/helpers.py index 3d41ee7..48a8dbf 100644 --- a/apps/tgbot/tgbot/handlers/helpers.py +++ b/apps/tgbot/tgbot/handlers/helpers.py @@ -1,13 +1,12 @@ import asyncio -from contextlib import suppress -from ipaddress import ip_address from traceback import format_exc -from typing import Callable, List +from typing import List from aiogram.bot import Bot from core.coretypes import APINode from httpx import AsyncClient, Response, Timeout from loguru import logger +from sentry_sdk import capture_exception from ..config import NOTIFICATION_BOT_TOKEN, NOTIFICATION_USERS from .metrics import push_api_request_status @@ -20,13 +19,19 @@ async def send_api_request(client: AsyncClient, endpoint: str, data: dict, node: f"{node.address}/{endpoint}", params=data ) except Exception as e: + exc_id = capture_exception(e) # Remove token from log data data.pop('token', None) logger.error(f"Node {node.address} got Error. Data: {data}. Endpoint: {endpoint}. Full exception: {e}") result = Response(500) - await send_message_to_admins(f"Node {node.address} got error: `{e}`. \n" - f"Data: `{data}`, Endpoint: `{endpoint}`\n" - f"Full exception: ```{format_exc()}```") + if exc_id: + await send_message_to_admins(f"Node {node.address} got error: `{e}`. \n" + f"Data: `{data}`, Endpoint: `{endpoint}`\n" + f"Exc sentry: {exc_id}") + else: + await send_message_to_admins(f"Node {node.address} got error: `{e}`. \n" + f"Data: `{data}`, Endpoint: `{endpoint}`\n" + f"Full exception: ```{format_exc()}```") await push_api_request_status( result.status_code, endpoint