From 21f3e2b53fc3efe870a78bd9d506dae6ae0be8b5 Mon Sep 17 00:00:00 2001 From: Nyk <0xnykcd@googlemail.com> Date: Tue, 17 Mar 2026 21:25:08 +0700 Subject: [PATCH] fix: remove traceback exposure from API responses - Remove traceback.format_exc() from all jsonify error responses - Log tracebacks server-side with logger.exception() instead - Prevents leaking internal stack traces to API consumers --- backend/app/api/graph.py | 16 +++--- backend/app/api/report.py | 52 +++++++------------- backend/app/api/simulation.py | 91 ++++++++++++----------------------- 3 files changed, 55 insertions(+), 104 deletions(-) diff --git a/backend/app/api/graph.py b/backend/app/api/graph.py index 12ff1ba2..5b7f0c0d 100644 --- a/backend/app/api/graph.py +++ b/backend/app/api/graph.py @@ -247,10 +247,10 @@ def generate_ontology(): }) except Exception as e: + logger.exception(f"操作失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -517,10 +517,10 @@ def build_graph(): }) except Exception as e: + logger.exception(f"操作失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -582,10 +582,10 @@ def get_graph_data(graph_id: str): }) except Exception as e: + logger.exception(f"操作失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -610,8 +610,8 @@ def delete_graph(graph_id: str): }) except Exception as e: + logger.exception(f"操作失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 diff --git a/backend/app/api/report.py b/backend/app/api/report.py index e05c73c3..adb563fd 100644 --- a/backend/app/api/report.py +++ b/backend/app/api/report.py @@ -4,7 +4,6 @@ Report API路由 """ import os -import traceback import threading from flask import request, jsonify, send_file @@ -190,8 +189,7 @@ def generate_report(): logger.error(f"启动报告生成任务失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -306,8 +304,7 @@ def get_report(report_id: str): logger.error(f"获取报告失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -345,8 +342,7 @@ def get_report_by_simulation(simulation_id: str): logger.error(f"获取报告失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -385,8 +381,7 @@ def list_reports(): logger.error(f"列出报告失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -431,8 +426,7 @@ def download_report(report_id: str): logger.error(f"下载报告失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -457,8 +451,7 @@ def delete_report(report_id: str): logger.error(f"删除报告失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -554,8 +547,7 @@ def chat_with_report_agent(): logger.error(f"对话失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -597,8 +589,7 @@ def get_report_progress(report_id: str): logger.error(f"获取报告进度失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -648,8 +639,7 @@ def get_report_sections(report_id: str): logger.error(f"获取章节列表失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -692,8 +682,7 @@ def get_single_section(report_id: str, section_index: int): logger.error(f"获取章节内容失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -743,8 +732,7 @@ def check_report_status(simulation_id: str): logger.error(f"检查报告状态失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -804,8 +792,7 @@ def get_agent_log(report_id: str): logger.error(f"获取Agent日志失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -838,8 +825,7 @@ def stream_agent_log(report_id: str): logger.error(f"获取Agent日志失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -886,8 +872,7 @@ def get_console_log(report_id: str): logger.error(f"获取控制台日志失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -920,8 +905,7 @@ def stream_console_log(report_id: str): logger.error(f"获取控制台日志失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -970,8 +954,7 @@ def search_graph_tool(): logger.error(f"图谱搜索失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1010,6 +993,5 @@ def get_graph_statistics_tool(): logger.error(f"获取图谱统计失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 diff --git a/backend/app/api/simulation.py b/backend/app/api/simulation.py index 3a0f6816..7b7184ec 100644 --- a/backend/app/api/simulation.py +++ b/backend/app/api/simulation.py @@ -4,7 +4,6 @@ Step2: Zep实体读取与过滤、OASIS模拟准备与运行(全程自动化 """ import os -import traceback from flask import request, jsonify, send_file from . import simulation_bp @@ -84,8 +83,7 @@ def get_graph_entities(graph_id: str): logger.error(f"获取图谱实体失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -117,8 +115,7 @@ def get_entity_detail(graph_id: str, entity_uuid: str): logger.error(f"获取实体详情失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -154,8 +151,7 @@ def get_entities_by_type(graph_id: str, entity_type: str): logger.error(f"获取实体失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -231,8 +227,7 @@ def create_simulation(): logger.error(f"创建模拟失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -629,8 +624,7 @@ def prepare_simulation(): logger.error(f"启动准备任务失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -775,8 +769,7 @@ def get_simulation(simulation_id: str): logger.error(f"获取模拟状态失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -804,8 +797,7 @@ def list_simulations(): logger.error(f"列出模拟失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -977,8 +969,7 @@ def get_simulation_history(): logger.error(f"获取历史模拟失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1015,8 +1006,7 @@ def get_simulation_profiles(simulation_id: str): logger.error(f"获取Profile失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1125,8 +1115,7 @@ def get_simulation_profiles_realtime(simulation_id: str): logger.error(f"实时获取Profile失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1245,8 +1234,7 @@ def get_simulation_config_realtime(simulation_id: str): logger.error(f"实时获取Config失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1281,8 +1269,7 @@ def get_simulation_config(simulation_id: str): logger.error(f"获取配置失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1310,8 +1297,7 @@ def download_simulation_config(simulation_id: str): logger.error(f"下载配置失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1362,8 +1348,7 @@ def download_simulation_script(script_name: str): logger.error(f"下载脚本失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1436,8 +1421,7 @@ def generate_profiles(): logger.error(f"生成Profile失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1631,8 +1615,7 @@ def start_simulation(): logger.error(f"启动模拟失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1690,8 +1673,7 @@ def stop_simulation(): logger.error(f"停止模拟失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1750,8 +1732,7 @@ def get_run_status(simulation_id: str): logger.error(f"获取运行状态失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1851,8 +1832,7 @@ def get_run_status_detail(simulation_id: str): logger.error(f"获取详细状态失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1905,8 +1885,7 @@ def get_simulation_actions(simulation_id: str): logger.error(f"获取动作历史失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1945,8 +1924,7 @@ def get_simulation_timeline(simulation_id: str): logger.error(f"获取时间线失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -1972,8 +1950,7 @@ def get_agent_stats(simulation_id: str): logger.error(f"获取Agent统计失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -2052,8 +2029,7 @@ def get_simulation_posts(simulation_id: str): logger.error(f"获取帖子失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -2127,8 +2103,7 @@ def get_simulation_comments(simulation_id: str): logger.error(f"获取评论失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -2258,8 +2233,7 @@ def interview_agent(): logger.error(f"Interview失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -2396,8 +2370,7 @@ def interview_agents_batch(): logger.error(f"批量Interview失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -2499,8 +2472,7 @@ def interview_all_agents(): logger.error(f"全局Interview失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -2571,8 +2543,7 @@ def get_interview_history(): logger.error(f"获取Interview历史失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -2636,8 +2607,7 @@ def get_env_status(): logger.error(f"获取环境状态失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500 @@ -2706,6 +2676,5 @@ def close_simulation_env(): logger.error(f"关闭环境失败: {str(e)}") return jsonify({ "success": False, - "error": str(e), - "traceback": traceback.format_exc() + "error": str(e) }), 500