From 53ea9e3970fc18e0c1d93b28e346985fe7d4b536 Mon Sep 17 00:00:00 2001 From: SXP-Simon Date: Tue, 10 Feb 2026 22:08:46 +0800 Subject: [PATCH] =?UTF-8?q?fix(RetryManager):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E9=87=8D=E8=AF=95=E9=80=BB=E8=BE=91=E4=B8=AD=E7=9A=84=20Base64?= =?UTF-8?q?=20=E7=BC=96=E7=A0=81=E5=B4=A9=E6=BA=83=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增加了对 html_render 返回本地文件路径的处理 (读取为 bytes) - 增加了对渲染结果的文件头校验,避免处理错误文本 --- src/infrastructure/scheduler/retry.py | 44 +++++++++++++++++++-------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/infrastructure/scheduler/retry.py b/src/infrastructure/scheduler/retry.py index bcd1816..75b804f 100644 --- a/src/infrastructure/scheduler/retry.py +++ b/src/infrastructure/scheduler/retry.py @@ -161,21 +161,39 @@ class RetryManager: ) # Fix: html_render might return URL (str) even if return_url=False in some implementations - if isinstance(image_data, str) and image_data.startswith( - ("http://", "https://") - ): - logger.warning( - f"[RetryManager] html_render 返回了 URL 而不是 bytes,尝试下载: {image_data}" - ) - async with aiohttp.ClientSession() as session: - async with session.get(image_data) as resp: - if resp.status == 200: - image_data = await resp.read() + if isinstance(image_data, str): + if image_data.startswith(("http://", "https://")): + logger.warning( + f"[RetryManager] html_render 返回了 URL 而不是 bytes,尝试下载: {image_data}" + ) + async with aiohttp.ClientSession() as session: + async with session.get(image_data) as resp: + if resp.status == 200: + image_data = await resp.read() + else: + logger.error( + f"[RetryManager] 下载重试图片失败: {resp.status}" + ) + image_data = None + else: + # 本地文件路径 + try: + import os + if os.path.exists(image_data): + with open(image_data, "rb") as f: + image_data = f.read() + + # 校验文件头 (防御性编程,避免发送错误文本) + if not image_data.startswith(b"\xff\xd8") and not image_data.startswith(b"\x89PNG"): + if len(image_data) < 1024 and (b"Error" in image_data or b"Exception" in image_data): + logger.error(f"[RetryManager] 渲染器生成了错误文件而非图片: {image_data.decode('utf-8', errors='ignore')}") + return False else: - logger.error( - f"[RetryManager] 下载重试图片失败: {resp.status}" - ) + logger.error(f"[RetryManager] 渲染器返回的路径不存在: {image_data}") image_data = None + except Exception as e: + logger.error(f"[RetryManager] 读取本地图片失败: {e}") + image_data = None if not image_data: logger.warning(