From c216ccb009d463b366906a249f1050adc6a902ff Mon Sep 17 00:00:00 2001 From: SXP-Simon Date: Sat, 20 Dec 2025 21:01:55 +0800 Subject: [PATCH] =?UTF-8?q?fix(auto=5Fscheduler):=20=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E8=B6=85=E6=97=B6=E5=92=8C=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F=E9=99=90=E5=88=B6=EF=BC=8C=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E5=8D=A1=E6=AD=BB=E6=88=96=E4=B8=8B=E8=BD=BD=E8=BF=87=E5=A4=A7?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E8=BF=87=E7=A8=8B=E7=9A=84=E5=81=A5?= =?UTF-8?q?=E5=A3=AE=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/scheduler/auto_scheduler.py | 43 +++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/src/scheduler/auto_scheduler.py b/src/scheduler/auto_scheduler.py index a0f448f..a13fa81 100644 --- a/src/scheduler/auto_scheduler.py +++ b/src/scheduler/auto_scheduler.py @@ -515,9 +515,9 @@ class AutoScheduler: if success: logger.info(f"群 {group_id} 图片报告发送成功") else: - # 图片生成失败,回退到文本 + # 图片发送失败,回退到文本 logger.warning( - f"群 {group_id} 图片报告生成失败(返回None),回退到文本报告" + f"群 {group_id} 发送图片报告失败,回退到文本报告" ) text_report = self.report_generator.generate_text_report( analysis_result @@ -525,6 +525,17 @@ class AutoScheduler: await self._send_text_message( group_id, f"📊 每日群聊分析报告:\n\n{text_report}" ) + else: + # 图片生成失败(返回None),回退到文本 + logger.warning( + f"群 {group_id} 图片报告生成失败(返回None),回退到文本报告" + ) + text_report = self.report_generator.generate_text_report( + analysis_result + ) + await self._send_text_message( + group_id, f"📊 每日群聊分析报告:\n\n{text_report}" + ) except Exception as img_e: logger.error( f"群 {group_id} 图片报告生成异常: {img_e},回退到文本报告" @@ -657,11 +668,33 @@ class AutoScheduler: # 2️⃣ base64 方式 # ========================================================= try: - async with aiohttp.ClientSession() as session: + # 设置请求超时和响应大小限制,避免卡死或下载过大 + timeout = aiohttp.ClientTimeout(total=10) # 10 秒超时 + async with aiohttp.ClientSession(timeout=timeout) as session: async with session.get(image_url) as resp: if resp.status != 200: - raise RuntimeError(f"status={resp.status}") - image_bytes = await resp.read() + logger.error(f"群 {group_id} base64 下载图片失败: status={resp.status}") + image_bytes = None + else: + max_bytes = 5 * 1024 * 1024 # 5 MiB 安全限制 + downloaded = 0 + chunks = [] + is_too_large = False + + async for chunk in resp.content.iter_chunked(64 * 1024): + downloaded += len(chunk) + if downloaded > max_bytes: + logger.error( + f"群 {group_id} base64 下载图片失败: 图片响应太大,超过 {max_bytes} 字节" + ) + is_too_large = True + break + chunks.append(chunk) + + if is_too_large: + image_bytes = None + else: + image_bytes = b"".join(chunks) except Exception as e: logger.error(f"群 {group_id} base64 下载图片失败: {e}") image_bytes = None