genz27 Warp commited on
Commit ·
0c95869
1
Parent(s): 4171d10
feat: 改进4K放大重试逻辑和日志大字段截断
Browse files- 4K放大失败时使用通用重试逻辑,支持403、reCAPTCHA、超时等多种错误类型
- 日志记录时对 encodedImage 等大字段进行截断处理,避免4K base64数据撑爆日志
Co-Authored-By: Warp <agent@warp.dev>
- src/core/logger.py +31 -1
- src/services/generation_handler.py +4 -3
src/core/logger.py
CHANGED
|
@@ -57,6 +57,32 @@ class DebugLogger:
|
|
| 57 |
"""Write separator line"""
|
| 58 |
self.logger.info(char * length)
|
| 59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
def log_request(
|
| 61 |
self,
|
| 62 |
method: str,
|
|
@@ -166,12 +192,16 @@ class DebugLogger:
|
|
| 166 |
# Body
|
| 167 |
self.logger.info("\n📦 Response Body:")
|
| 168 |
if isinstance(body, (dict, list)):
|
| 169 |
-
|
|
|
|
|
|
|
| 170 |
self.logger.info(body_str)
|
| 171 |
elif isinstance(body, str):
|
| 172 |
# Try to parse as JSON
|
| 173 |
try:
|
| 174 |
parsed = json.loads(body)
|
|
|
|
|
|
|
| 175 |
body_str = json.dumps(parsed, indent=2, ensure_ascii=False)
|
| 176 |
self.logger.info(body_str)
|
| 177 |
except:
|
|
|
|
| 57 |
"""Write separator line"""
|
| 58 |
self.logger.info(char * length)
|
| 59 |
|
| 60 |
+
def _truncate_large_fields(self, data: Any, max_length: int = 200) -> Any:
|
| 61 |
+
"""对大字段进行截断处理,特别是 base64 编码的图片数据
|
| 62 |
+
|
| 63 |
+
Args:
|
| 64 |
+
data: 要处理的数据
|
| 65 |
+
max_length: 字符串字段的最大长度
|
| 66 |
+
|
| 67 |
+
Returns:
|
| 68 |
+
截断后的数据副本
|
| 69 |
+
"""
|
| 70 |
+
if isinstance(data, dict):
|
| 71 |
+
result = {}
|
| 72 |
+
for key, value in data.items():
|
| 73 |
+
# 对特定的大字段进行截断
|
| 74 |
+
if key in ("encodedImage", "base64", "imageData", "data") and isinstance(value, str) and len(value) > max_length:
|
| 75 |
+
result[key] = f"{value[:100]}... (truncated, total {len(value)} chars)"
|
| 76 |
+
else:
|
| 77 |
+
result[key] = self._truncate_large_fields(value, max_length)
|
| 78 |
+
return result
|
| 79 |
+
elif isinstance(data, list):
|
| 80 |
+
return [self._truncate_large_fields(item, max_length) for item in data]
|
| 81 |
+
elif isinstance(data, str) and len(data) > 10000:
|
| 82 |
+
# 对超长字符串进行截断(可能是未知的 base64 字段)
|
| 83 |
+
return f"{data[:100]}... (truncated, total {len(data)} chars)"
|
| 84 |
+
return data
|
| 85 |
+
|
| 86 |
def log_request(
|
| 87 |
self,
|
| 88 |
method: str,
|
|
|
|
| 192 |
# Body
|
| 193 |
self.logger.info("\n📦 Response Body:")
|
| 194 |
if isinstance(body, (dict, list)):
|
| 195 |
+
# 对大字段进行截断处理
|
| 196 |
+
body_to_log = self._truncate_large_fields(body)
|
| 197 |
+
body_str = json.dumps(body_to_log, indent=2, ensure_ascii=False)
|
| 198 |
self.logger.info(body_str)
|
| 199 |
elif isinstance(body, str):
|
| 200 |
# Try to parse as JSON
|
| 201 |
try:
|
| 202 |
parsed = json.loads(body)
|
| 203 |
+
# 对大字段进行截断处理
|
| 204 |
+
parsed = self._truncate_large_fields(parsed)
|
| 205 |
body_str = json.dumps(parsed, indent=2, ensure_ascii=False)
|
| 206 |
self.logger.info(body_str)
|
| 207 |
except:
|
src/services/generation_handler.py
CHANGED
|
@@ -915,10 +915,11 @@ class GenerationHandler:
|
|
| 915 |
error_str = str(e)
|
| 916 |
debug_logger.log_error(f"[UPSAMPLE] 放大失败 (尝试 {retry_attempt + 1}/{max_retries}): {error_str}")
|
| 917 |
|
| 918 |
-
# 检查是否是
|
| 919 |
-
|
|
|
|
| 920 |
if stream:
|
| 921 |
-
yield self._create_stream_chunk(f"⚠️ 放大遇到
|
| 922 |
# 等待一小段时间后重试
|
| 923 |
await asyncio.sleep(1)
|
| 924 |
continue
|
|
|
|
| 915 |
error_str = str(e)
|
| 916 |
debug_logger.log_error(f"[UPSAMPLE] 放大失败 (尝试 {retry_attempt + 1}/{max_retries}): {error_str}")
|
| 917 |
|
| 918 |
+
# 检查是否是可重试错误(403、reCAPTCHA、超时等)
|
| 919 |
+
retry_reason = self.flow_client._get_retry_reason(error_str)
|
| 920 |
+
if retry_reason and retry_attempt < max_retries - 1:
|
| 921 |
if stream:
|
| 922 |
+
yield self._create_stream_chunk(f"⚠️ 放大遇到{retry_reason},正在重试 ({retry_attempt + 2}/{max_retries})...\n")
|
| 923 |
# 等待一小段时间后重试
|
| 924 |
await asyncio.sleep(1)
|
| 925 |
continue
|