fix(api): don't leak stack traces in simulation error responses
Return only the exception message to clients; log full traceback server-side via logger.error(..., exc_info=True). Prevents disclosure of internal paths, library versions, and code structure (CWE-209).
This commit is contained in:
parent
60757b3c82
commit
b2e5b7e8de
|
|
@ -4,7 +4,6 @@ Step2: Zep实体读取与过滤、OASIS模拟准备与运行(全程自动化
|
|||
"""
|
||||
|
||||
import os
|
||||
import traceback
|
||||
from contextlib import nullcontext
|
||||
from flask import request, jsonify, send_file
|
||||
|
||||
|
|
@ -112,11 +111,10 @@ def get_graph_entities(graph_id: str):
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取图谱实体失败: {str(e)}")
|
||||
logger.error(f"获取图谱实体失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -145,11 +143,10 @@ def get_entity_detail(graph_id: str, entity_uuid: str):
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取实体详情失败: {str(e)}")
|
||||
logger.error(f"获取实体详情失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -182,11 +179,10 @@ def get_entities_by_type(graph_id: str, entity_type: str):
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取实体失败: {str(e)}")
|
||||
logger.error(f"获取实体失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -259,11 +255,10 @@ def create_simulation():
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"创建模拟失败: {str(e)}")
|
||||
logger.error(f"创建模拟失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -632,7 +627,7 @@ def prepare_simulation():
|
|||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"准备模拟失败: {str(e)}")
|
||||
logger.error(f"准备模拟失败: {str(e)}", exc_info=True)
|
||||
task_manager.fail_task(task_id, str(e))
|
||||
|
||||
# 更新模拟状态为失败
|
||||
|
|
@ -666,11 +661,10 @@ def prepare_simulation():
|
|||
}), 404
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"启动准备任务失败: {str(e)}")
|
||||
logger.error(f"启动准备任务失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -780,7 +774,7 @@ def get_prepare_status():
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"查询任务状态失败: {str(e)}")
|
||||
logger.error(f"查询任务状态失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e)
|
||||
|
|
@ -812,11 +806,10 @@ def get_simulation(simulation_id: str):
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取模拟状态失败: {str(e)}")
|
||||
logger.error(f"获取模拟状态失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -841,11 +834,10 @@ def list_simulations():
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"列出模拟失败: {str(e)}")
|
||||
logger.error(f"列出模拟失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -1014,11 +1006,10 @@ def get_simulation_history():
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取历史模拟失败: {str(e)}")
|
||||
logger.error(f"获取历史模拟失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -1052,11 +1043,10 @@ def get_simulation_profiles(simulation_id: str):
|
|||
}), 404
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取Profile失败: {str(e)}")
|
||||
logger.error(f"获取Profile失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -1167,11 +1157,10 @@ def get_simulation_profiles_realtime(simulation_id: str):
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"实时获取Profile失败: {str(e)}")
|
||||
logger.error(f"实时获取Profile失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -1297,11 +1286,10 @@ def get_simulation_config_realtime(simulation_id: str):
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"实时获取Config失败: {str(e)}")
|
||||
logger.error(f"实时获取Config失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -1333,11 +1321,10 @@ def get_simulation_config(simulation_id: str):
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取配置失败: {str(e)}")
|
||||
logger.error(f"获取配置失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -1362,11 +1349,10 @@ def download_simulation_config(simulation_id: str):
|
|||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"下载配置失败: {str(e)}")
|
||||
logger.error(f"下载配置失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -1414,11 +1400,10 @@ def download_simulation_script(script_name: str):
|
|||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"下载脚本失败: {str(e)}")
|
||||
logger.error(f"下载脚本失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -1488,11 +1473,10 @@ def generate_profiles():
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"生成Profile失败: {str(e)}")
|
||||
logger.error(f"生成Profile失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -1777,11 +1761,10 @@ def start_simulation():
|
|||
}), 400
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"启动模拟失败: {str(e)}")
|
||||
logger.error(f"启动模拟失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -1844,7 +1827,7 @@ def stop_simulation():
|
|||
}), 400
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"停止模拟失败: {str(e)}")
|
||||
logger.error(f"停止模拟失败: {str(e)}", exc_info=True)
|
||||
simulation_id = (request.get_json(silent=True) or {}).get('simulation_id')
|
||||
if simulation_id:
|
||||
manager = SimulationManager()
|
||||
|
|
@ -1855,8 +1838,7 @@ def stop_simulation():
|
|||
manager._save_simulation_state(state)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -1912,11 +1894,10 @@ def get_run_status(simulation_id: str):
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取运行状态失败: {str(e)}")
|
||||
logger.error(f"获取运行状态失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -2013,11 +1994,10 @@ def get_run_status_detail(simulation_id: str):
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取详细状态失败: {str(e)}")
|
||||
logger.error(f"获取详细状态失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -2067,11 +2047,10 @@ def get_simulation_actions(simulation_id: str):
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取动作历史失败: {str(e)}")
|
||||
logger.error(f"获取动作历史失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -2107,11 +2086,10 @@ def get_simulation_timeline(simulation_id: str):
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取时间线失败: {str(e)}")
|
||||
logger.error(f"获取时间线失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -2134,11 +2112,10 @@ def get_agent_stats(simulation_id: str):
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取Agent统计失败: {str(e)}")
|
||||
logger.error(f"获取Agent统计失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -2214,11 +2191,10 @@ def get_simulation_posts(simulation_id: str):
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取帖子失败: {str(e)}")
|
||||
logger.error(f"获取帖子失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -2291,11 +2267,10 @@ def get_simulation_comments(simulation_id: str):
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取评论失败: {str(e)}")
|
||||
logger.error(f"获取评论失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -2422,11 +2397,10 @@ def interview_agent():
|
|||
}), 504
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Interview失败: {str(e)}")
|
||||
logger.error(f"Interview失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -2560,11 +2534,10 @@ def interview_agents_batch():
|
|||
}), 504
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"批量Interview失败: {str(e)}")
|
||||
logger.error(f"批量Interview失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -2663,11 +2636,10 @@ def interview_all_agents():
|
|||
}), 504
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"全局Interview失败: {str(e)}")
|
||||
logger.error(f"全局Interview失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -2735,11 +2707,10 @@ def get_interview_history():
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取Interview历史失败: {str(e)}")
|
||||
logger.error(f"获取Interview历史失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -2800,11 +2771,10 @@ def get_env_status():
|
|||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取环境状态失败: {str(e)}")
|
||||
logger.error(f"获取环境状态失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
|
|
@ -2870,9 +2840,8 @@ def close_simulation_env():
|
|||
}), 400
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"关闭环境失败: {str(e)}")
|
||||
logger.error(f"关闭环境失败: {str(e)}", exc_info=True)
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
|
|
|||
Loading…
Reference in New Issue