PhysicsCorrection/scripts/diagnose_full_error.py

222 lines
8.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
完整错误信息诊断脚本
运行工作流并捕获完整的错误信息
"""
import sys
import os
import json
import traceback
from datetime import datetime
# 添加项目路径
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, project_root)
sys.path.insert(0, os.path.join(project_root, 'src'))
from langgraph.runtime import Runtime
from coze_coding_utils.runtime_ctx.context import Context, new_context
def run_test_with_full_error_capture():
"""运行测试并捕获完整错误信息"""
# 准备测试数据
test_data = {
"student_homework": [
{
"student_id": 1,
"student_name": "张三呀",
"homework_images": [
"https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/18/69baa4f5-4826-4901-00e1-c6e66f02947f.jpg?x-oss-process=image/resize,w_1000",
"https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/25/69c344ba-4826-4901-00e1-c6ff235a12b2.jpg?x-oss-process=image/resize,w_1000",
"https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/25/69c344ba-4826-4901-00e1-c7055a396422.jpg?x-oss-process=image/resize,w_1000",
"https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/25/69c344ba-4826-4901-00e1-c6fe7f9c07ef.jpg?x-oss-process=image/resize,w_1000"
]
},
{
"student_id": 2,
"student_name": "李四呀",
"homework_images": [
"https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/25/69c344ba-4826-4901-00e1-c70052d895e3.jpg?x-oss-process=image/resize,w_1000",
"https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/25/69c344ba-4826-4901-00e1-c6fc6ca7c4bf.png?x-oss-process=image/resize,w_1000",
"https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/25/69c33f31-4826-4901-00e1-c6fb50697e06.png?x-oss-process=image/resize,w_1000",
"https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/23/69c1029b-4826-4901-00e1-c6f614bc06d9.jpg?x-oss-process=image/resize,w_1000",
"https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/25/69c344ba-4826-4901-00e1-c6fd479e0a0e.jpg?x-oss-process=image/resize,w_1000",
"https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/23/69c1029b-4826-4901-00e1-c6f569b31a14.jpeg?x-oss-process=image/resize,w_1000"
]
}
],
"answer_doc_url": "https://dpc-oss.23544.com/umsupload/2026/03/25/69c353d0-4826-4901-00e1-c7081bcab988.docx",
"comment_max_length": 50,
"max_concurrent": 5,
"grade_standards": {}
}
print("=" * 80)
print("开始运行完整错误诊断测试")
print("=" * 80)
print(f"测试数据: {len(test_data['student_homework'])} 个学生")
total_images = sum(len(s['homework_images']) for s in test_data['student_homework'])
print(f"总图片数: {total_images}")
print(f"答案文档: {test_data['answer_doc_url'][:50]}...")
print("=" * 80)
print()
# 初始化上下文
ctx = new_context(method="run")
try:
# 导入主图
from graphs.graph import main_graph
print("✓ 成功导入主图")
print()
# 运行测试
print("开始运行工作流...")
print("-" * 80)
result = main_graph.invoke(test_data, config={"recursion_limit": 100})
print("-" * 80)
print()
print("=" * 80)
print("✓ 测试成功!")
print("=" * 80)
print()
# 输出结果摘要
if "student_results" in result:
for student_result in result["student_results"]:
# StudentResult 是 Pydantic 对象,使用属性访问而不是 .get()
student_name = getattr(student_result, "student_name", "未知")
total_images = getattr(student_result, "total_images", 0)
total_score = getattr(student_result, "total_score", 0)
full_score = getattr(student_result, "full_score", 0)
grade = getattr(student_result, "grade", "N/A")
print(f"学生: {student_name}")
print(f" 图片数: {total_images}")
print(f" 得分: {total_score}/{full_score}")
print(f" 等级: {grade}")
print()
# 保存完整结果到文件(先转换为 dict
result_dict = result.model_dump() if hasattr(result, 'model_dump') else result
result_file = f"/tmp/diagnostic_result_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
with open(result_file, 'w', encoding='utf-8') as f:
json.dump(result_dict, f, ensure_ascii=False, indent=2)
print(f"完整结果已保存到: {result_file}")
return True
except Exception as e:
print("-" * 80)
print()
print("=" * 80)
print("✗ 测试失败!")
print("=" * 80)
print()
print("错误类型:", type(e).__name__)
print("错误消息:", str(e))
print()
print("完整堆栈跟踪:")
print("-" * 80)
traceback.print_exc()
print("-" * 80)
print()
# 保存错误信息到文件
error_file = f"/tmp/diagnostic_error_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
with open(error_file, 'w', encoding='utf-8') as f:
f.write(f"错误类型: {type(e).__name__}\n")
f.write(f"错误消息: {str(e)}\n")
f.write("\n完整堆栈跟踪:\n")
f.write("=" * 80 + "\n")
traceback.print_exc(file=f)
print(f"错误信息已保存到: {error_file}")
print()
# 分析错误类型
print("错误分析:")
print("-" * 80)
error_str = str(e).lower()
if "404" in error_str or "not found" in error_str:
print("⚠️ 404 错误:资源不存在")
print(" 可能原因:")
print(" 1. URL 已过期(签名 URL 有时效性)")
print(" 2. 文件已被删除或移动")
print(" 3. URL 拼写错误")
elif "403" in error_str or "forbidden" in error_str:
print("⚠️ 403 错误:禁止访问")
print(" 可能原因:")
print(" 1. 访问权限不足")
print(" 2. 需要 IP 白名单")
print(" 3. 需要认证")
elif "401" in error_str or "unauthorized" in error_str:
print("⚠️ 401 错误:未授权")
print(" 可能原因:")
print(" 1. API 密钥无效")
print(" 2. 认证失败")
print(" 3. Token 过期")
elif "timeout" in error_str:
print("⚠️ 超时错误")
print(" 可能原因:")
print(" 1. 网络连接慢")
print(" 2. 服务器响应慢")
print(" 3. 图片或文档太大")
elif "connection" in error_str or "network" in error_str:
print("⚠️ 网络连接错误")
print(" 可能原因:")
print(" 1. 无法连接到外部网络")
print(" 2. DNS 解析失败")
print(" 3. 防火墙阻止")
elif "html" in error_str:
print("⚠️ HTML 错误页面")
print(" 可能原因:")
print(" 1. URL 返回了 404/403/500 错误页面")
print(" 2. 网络重定向失败")
print(" 3. CDN 或代理返回错误")
elif "json" in error_str:
print("⚠️ JSON 解析错误")
print(" 可能原因:")
print(" 1. LLM 返回的不是有效的 JSON")
print(" 2. JSON 格式错误")
print(" 3. 缺少必需字段")
elif "llm" in error_str or "model" in error_str:
print("⚠️ LLM 调用错误")
print(" 可能原因:")
print(" 1. LLM 服务不可用")
print(" 2. 模型配置错误")
print(" 3. API 配额不足")
else:
print("⚠️ 未知错误类型")
print(" 请查看上面的错误详情和堆栈跟踪")
print()
return False
if __name__ == "__main__":
print()
print("=" * 80)
print("初中数学作业批改工作流 - 完整错误诊断")
print("=" * 80)
print()
success = run_test_with_full_error_capture()
print()
print("=" * 80)
if success:
print("诊断完成:工作流运行正常")
sys.exit(0)
else:
print("诊断完成:发现错误,请查看上面的错误详情")
sys.exit(1)