Files
aiagent/backend/app/core/error_handler.py
renjianbo 0608161c82 feat: 完善企业场景多线路由与执行稳定性
补齐平台模板与场景 DSL、预算控制、执行看板和企业场景脚本,增强 Windows 启动/迁移与前端代理和聊天会话记忆,修复执行创建阶段 500 与异步链路排障体验。

Made-with: Cursor
2026-04-09 21:58:53 +08:00

95 lines
2.9 KiB
Python
Raw 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.
"""
全局错误处理器
"""
import logging
import traceback
from fastapi import Request, status
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from sqlalchemy.exc import SQLAlchemyError
from app.core.exceptions import BaseAPIException
from app.core.config import settings
logger = logging.getLogger(__name__)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
"""处理验证错误"""
errors = []
for error in exc.errors():
field = ".".join(str(loc) for loc in error.get("loc", []))
errors.append({
"field": field,
"message": error.get("msg"),
"type": error.get("type")
})
logger.warning(f"验证错误: {errors}")
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content={
"error": "VALIDATION_ERROR",
"message": "请求参数验证失败",
"details": errors
}
)
async def api_exception_handler(request: Request, exc: BaseAPIException):
"""处理自定义API异常"""
logger.error(f"API异常: {exc.detail} (错误码: {exc.error_code})")
return JSONResponse(
status_code=exc.status_code,
content={
"error": exc.error_code or "API_ERROR",
"message": exc.detail
}
)
async def sqlalchemy_exception_handler(request: Request, exc: SQLAlchemyError):
"""处理数据库错误"""
orig = getattr(exc, "orig", None)
detail = str(orig) if orig is not None else str(exc)
logger.error(f"数据库错误: {detail}", exc_info=True)
user_msg = "数据库操作失败,请稍后重试"
# MySQL 1054 / 常见 DDL 滞后:模型已增列但库未 alembic upgrade
if "Unknown column" in detail or "(1054," in detail or "1054" in detail:
user_msg = (
"数据库表结构与当前代码不一致(常见为缺少 executions 新列等)。"
"请在 backend 目录执行alembic upgrade head然后重启 API 与 Celery。"
)
payload: dict = {
"error": "DATABASE_ERROR",
"message": user_msg,
}
if settings.DEBUG:
payload["detail"] = detail[:4000]
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content=payload,
)
async def general_exception_handler(request: Request, exc: Exception):
"""处理通用异常"""
logger.error(f"未处理的异常: {str(exc)}", exc_info=True)
logger.error(f"异常堆栈: {traceback.format_exc()}")
payload: dict = {
"error": "INTERNAL_ERROR",
"message": "服务器内部错误,请稍后重试",
}
if settings.DEBUG:
payload["detail"] = str(exc)[:4000]
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content=payload,
)