fix: 修复 /api/v1/sessions 500 错误

- 修复 validate_ip_and_apikey 装饰器无法获取 Request 对象的问题:
  原代码通过遍历 args 查找 Request 对象,但 FastAPI 端点使用 Pydantic
  模型作为参数时找不到 Request,导致装饰器跳过验证并可能引发异常。
  改为显式声明 request: Request 作为 wrapper 的第一个参数,由 FastAPI 自动注入。

- 增强 ensure_user_hermes_env 的错误处理:
  添加 try/except 包裹,检查 BASE_HERMES_PATH 是否存在,
  将未处理的异常转为带详细信息的 HTTPException(500)。
This commit is contained in:
yumoqing 2026-04-27 15:40:25 +08:00
parent 2152ae9d40
commit 6adae569be

67
main.py
View File

@ -165,22 +165,7 @@ def validate_ip_and_apikey():
"""Decorator to validate IP and API key for protected endpoints"""
def decorator(func):
@wraps(func)
async def wrapper(*args, **kwargs):
# Extract request object (assuming it's the first argument after self)
request = None
for arg in args:
if isinstance(arg, Request):
request = arg
break
if request is None:
# Try to find request in kwargs
request = kwargs.get('request')
if request is None:
# If no request object found, skip validation
return await func(*args, **kwargs)
async def wrapper(request: Request, *args, **kwargs):
# IP validation
if config['security']['enable_ip_check']:
client_ip = get_real_ip(request)
@ -241,27 +226,37 @@ def get_user_hermes_path(user_id: str) -> str:
def ensure_user_hermes_env(user_id: str):
"""Ensure user has isolated Hermes environment"""
user_base_path = get_user_hermes_path(user_id)
user_hermes_path = os.path.join(user_base_path, "hermes-agent")
user_dot_hermes = os.path.join(user_base_path, ".hermes")
if not os.path.exists(user_hermes_path):
os.makedirs(user_base_path, exist_ok=True, mode=0o700)
shutil.copytree(
BASE_HERMES_PATH,
user_hermes_path,
dirs_exist_ok=True,
ignore=shutil.ignore_patterns('.git', '__pycache__', '*.pyc', '.venv', 'web_dist')
)
os.makedirs(user_dot_hermes, exist_ok=True, mode=0o700)
venv_link = os.path.join(user_hermes_path, '.venv')
if not os.path.exists(venv_link):
os.symlink(
os.path.join(BASE_HERMES_PATH, '.venv'),
venv_link
try:
user_base_path = get_user_hermes_path(user_id)
user_hermes_path = os.path.join(user_base_path, "hermes-agent")
user_dot_hermes = os.path.join(user_base_path, ".hermes")
if not os.path.exists(user_hermes_path):
os.makedirs(user_base_path, exist_ok=True, mode=0o700)
if not os.path.exists(BASE_HERMES_PATH):
raise FileNotFoundError(f"Base Hermes path not found: {BASE_HERMES_PATH}")
shutil.copytree(
BASE_HERMES_PATH,
user_hermes_path,
dirs_exist_ok=True,
ignore=shutil.ignore_patterns('.git', '__pycache__', '*.pyc', '.venv', 'web_dist')
)
return user_hermes_path
os.makedirs(user_dot_hermes, exist_ok=True, mode=0o700)
venv_link = os.path.join(user_hermes_path, '.venv')
if not os.path.exists(venv_link):
os.symlink(
os.path.join(BASE_HERMES_PATH, '.venv'),
venv_link
)
return user_hermes_path
except HTTPException:
raise
except Exception as e:
print(f"ERROR: Failed to ensure user Hermes env for {user_id}: {e}")
import traceback
traceback.print_exc()
raise HTTPException(status_code=500, detail=f"Failed to initialize user environment: {str(e)}")
@app.get("/health")
@validate_ip_and_apikey()