diff --git a/.env.example b/.env.example
index a108f82..2afe606 100644
--- a/.env.example
+++ b/.env.example
@@ -47,7 +47,7 @@ LOGGER_LOCALS_MAX_DEPTH=0
LOGGER_LOCALS_MAX_LENGTH=10
LOGGER_LOCALS_MAX_STRING=80
# 可被 logger 打印的 record 的名称(默认包含了 LOGGER_NAME )
-LOGGER_FILTERED_NAMES=["uvicorn"]
+LOGGER_FILTERED_NAMES=["uvicorn","ErrorPush"]
# 超时配置 可选配置项
diff --git a/modules/error/sentry.py b/modules/error/sentry.py
deleted file mode 100644
index d9bc428..0000000
--- a/modules/error/sentry.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import os
-
-import sentry_sdk
-from git.repo import Repo
-from git.repo.fun import rev_parse
-from sentry_sdk.integrations.excepthook import ExcepthookIntegration
-from sentry_sdk.integrations.httpx import HttpxIntegration
-from sentry_sdk.integrations.logging import LoggingIntegration
-from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
-from telegram import Update
-
-from core.config import config
-from utils.log import logger
-
-repo = Repo(os.getcwd())
-sentry_sdk_git_hash = rev_parse(repo, "HEAD").hexsha
-sentry_sdk.init(
- config.error.sentry_dsn,
- traces_sample_rate=1.0,
- release=sentry_sdk_git_hash,
- environment="production",
- integrations=[
- HttpxIntegration(),
- ExcepthookIntegration(always_run=False),
- LoggingIntegration(event_level=50),
- SqlalchemyIntegration(),
- ],
-)
-
-
-class Sentry:
- @staticmethod
- def report_error(update: object, exc_info):
- if not config.error.sentry_dsn:
- return
- logger.info("正在上传日记到 sentry")
- message: str = ""
- chat_id: int = 0
- user_id: int = 0
- if isinstance(update, Update):
- if update.effective_user:
- chat_id = update.effective_user.id
- if update.effective_chat:
- user_id = update.effective_chat.id
- if update.effective_message:
- if update.effective_message.text:
- message = update.effective_message.text
- sentry_sdk.set_context("Target", {"ChatID": str(chat_id), "UserID": str(user_id), "Msg": message})
- sentry_sdk.capture_exception(exc_info)
- logger.success("上传日记到 sentry 成功")
diff --git a/modules/errorpush/__init__.py b/modules/errorpush/__init__.py
new file mode 100644
index 0000000..8126606
--- /dev/null
+++ b/modules/errorpush/__init__.py
@@ -0,0 +1,5 @@
+from .pb import PbClient, PbClientException
+from .sentry import SentryClient, SentryClientException
+
+
+__all__ = ["PbClient", "PbClientException", "SentryClient", "SentryClientException"]
diff --git a/modules/errorpush/logger.py b/modules/errorpush/logger.py
new file mode 100644
index 0000000..43ace01
--- /dev/null
+++ b/modules/errorpush/logger.py
@@ -0,0 +1,3 @@
+import logging
+
+logger = logging.getLogger("ErrorPush")
diff --git a/modules/error/pb.py b/modules/errorpush/pb.py
similarity index 50%
rename from modules/error/pb.py
rename to modules/errorpush/pb.py
index f2f22b6..b8d25ea 100644
--- a/modules/error/pb.py
+++ b/modules/errorpush/pb.py
@@ -2,23 +2,42 @@ from typing import Optional
import httpx
-from core.config import config
from utils.log import logger
+__all__ = ["PbClient", "PbClientException"]
+
+
+class PbClientException(Exception):
+ pass
+
class PbClient:
- def __init__(self):
+ def __init__(self, pb_url: Optional[str] = None, pb_sunset: Optional[int] = None, pb_max_lines: int = 1000):
+ """PbClient
+ :param pb_url:
+ :param pb_sunset: 自动销毁时间 单位为秒
+ :param pb_max_lines:
+ """
self.client = httpx.AsyncClient()
- self.PB_API = config.error.pb_url
- self.sunset: int = config.error.pb_sunset # 自动销毁时间 单位为秒
+ self.PB_API = pb_url
+ self.sunset: int = pb_sunset
self.private: bool = True
- self.max_lines: int = config.error.pb_max_lines
+ self.max_lines: int = pb_max_lines
+
+ @property
+ def enabled(self) -> bool:
+ return bool(self.PB_API)
async def create_pb(self, content: str) -> Optional[str]:
+ try:
+ return await self._create_pb(content)
+ except Exception as exc:
+ raise PbClientException from exc
+
+ async def _create_pb(self, content: str) -> Optional[str]:
if not self.PB_API:
return None
- logger.info("正在上传日记到 pb")
- content = "\n".join(content.splitlines()[-self.max_lines:]) + "\n"
+ content = "\n".join(content.splitlines()[-self.max_lines :]) + "\n"
data = {
"c": content,
}
@@ -30,5 +49,4 @@ class PbClient:
if result.is_error:
logger.warning("上传日记到 pb 失败 status_code[%s]", result.status_code)
return None
- logger.success("上传日记到 pb 成功")
return result.headers.get("location")
diff --git a/modules/errorpush/sentry.py b/modules/errorpush/sentry.py
new file mode 100644
index 0000000..5683e6d
--- /dev/null
+++ b/modules/errorpush/sentry.py
@@ -0,0 +1,63 @@
+import os
+from typing import Optional
+
+import sentry_sdk
+from git.repo import Repo
+from git.repo.fun import rev_parse
+from sentry_sdk.integrations.excepthook import ExcepthookIntegration
+from sentry_sdk.integrations.httpx import HttpxIntegration
+from sentry_sdk.integrations.logging import LoggingIntegration
+from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
+from telegram import Update
+
+__all__ = ["SentryClient", "SentryClientException"]
+
+
+class SentryClientException(Exception):
+ pass
+
+
+class SentryClient:
+ def __init__(self, sentry_dsn: Optional[str] = None):
+ self.sentry_dsn = sentry_dsn
+ if sentry_dsn:
+ repo = Repo(os.getcwd())
+ sentry_sdk_git_hash = rev_parse(repo, "HEAD").hexsha
+ sentry_sdk.init(
+ sentry_dsn,
+ traces_sample_rate=1.0,
+ release=sentry_sdk_git_hash,
+ environment="production",
+ integrations=[
+ HttpxIntegration(),
+ ExcepthookIntegration(always_run=False),
+ LoggingIntegration(event_level=50),
+ SqlalchemyIntegration(),
+ ],
+ )
+
+ @property
+ def enabled(self) -> bool:
+ return bool(self.sentry_dsn)
+
+ def report_error(self, update: object, exc_info):
+ try:
+ return self._report_error(update, exc_info)
+ except Exception as exc:
+ raise SentryClientException from exc
+
+ def _report_error(self, update: object, exc_info):
+ if not self.sentry_dsn:
+ return
+ message: str = ""
+ chat_id: int = 0
+ user_id: int = 0
+ if isinstance(update, Update):
+ if update.effective_user:
+ chat_id = update.effective_user.id
+ if update.effective_chat:
+ user_id = update.effective_chat.id
+ if update.effective_message and update.effective_message.text:
+ message = update.effective_message.text
+ sentry_sdk.set_context("Target", {"ChatID": str(chat_id), "UserID": str(user_id), "Msg": message})
+ sentry_sdk.capture_exception(exc_info)
diff --git a/plugins/system/errorhandler.py b/plugins/system/errorhandler.py
index 0c2a592..5408a84 100644
--- a/plugins/system/errorhandler.py
+++ b/plugins/system/errorhandler.py
@@ -10,9 +10,9 @@ from telegram.error import BadRequest, Forbidden
from telegram.ext import CallbackContext
from core.bot import bot
+from core.config import config
from core.plugin import Plugin, error_handler
-from modules.error.pb import PbClient
-from modules.error.sentry import Sentry
+from modules.errorpush import PbClient, SentryClient, PbClientException, SentryClientException
from utils.log import logger
notice_chat_id = bot.config.error.notification_chat_id
@@ -23,8 +23,8 @@ if not os.path.exists(logs_dir):
report_dir = os.path.join(current_dir, "report")
if not os.path.exists(report_dir):
os.mkdir(report_dir)
-pb_client = PbClient()
-sentry = Sentry()
+pb_client = PbClient(config.error.pb_url, config.error.pb_sunset, config.error.pb_max_lines)
+sentry = SentryClient(config.error.sentry_dsn)
class ErrorHandler(Plugin):
@@ -91,19 +91,29 @@ class ErrorHandler(Plugin):
except (BadRequest, Forbidden) as exc:
logger.error(f"发送 update_id[{update.update_id}] 错误信息失败 错误信息为")
logger.exception(exc)
- try:
- pb_url = await pb_client.create_pb(error_text)
- if pb_url:
- await context.bot.send_message(
- chat_id=notice_chat_id,
- text=f"错误信息已上传至 fars 请查看",
- parse_mode=ParseMode.HTML,
- )
- except Exception as exc: # pylint: disable=W0703
- logger.error("上传错误信息至 fars 失败")
- logger.exception(exc)
- try:
- sentry.report_error(update, (type(context.error), context.error, context.error.__traceback__))
- except Exception as exc: # pylint: disable=W0703
- logger.error("上传错误信息至 sentry 失败")
- logger.exception(exc)
+ if pb_client.enabled:
+ logger.info("正在上传日记到 pb")
+ try:
+ pb_url = await pb_client.create_pb(error_text)
+ if pb_url:
+ logger.success("上传日记到 pb 成功")
+ await context.bot.send_message(
+ chat_id=notice_chat_id,
+ text=f"错误信息已上传至 fars 请查看",
+ parse_mode=ParseMode.HTML,
+ )
+ except PbClientException as exc:
+ logger.warning("上传错误信息至 fars 失败", exc_info=exc)
+ except Exception as exc:
+ logger.error("上传错误信息至 fars 失败")
+ logger.exception(exc)
+ if sentry.enabled:
+ logger.info("正在上传日记到 sentry")
+ try:
+ sentry.report_error(update, (type(context.error), context.error, context.error.__traceback__))
+ logger.success("上传日记到 sentry 成功")
+ except SentryClientException as exc:
+ logger.warning("上传错误信息至 sentry 失败", exc_info=exc)
+ except Exception as exc:
+ logger.error("上传错误信息至 sentry 失败")
+ logger.exception(exc)