You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

5.3 KiB

项目相关 API 响应格式与异常处理标准化

变更日期: 2026-02-11
变更类型: 重构 (Refactoring)
影响范围: projects.py, project_resources.py, project_elements.py, project_element_tags.py
Breaking Change: 否

背景

为了统一后端 API 的响应格式和异常处理机制,需要将项目相关的 4 个 API 文件迁移到标准格式。参考 ai_conversations.py 的实现规范,确保:

  1. 查询参数支持 camelCase(使用 alias 参数)
  2. 响应格式使用 SuccessResponse 包装
  3. 异常处理统一使用 app.core.exceptions 中的自定义异常类

变更内容

1. 统一异常处理

之前 (使用 HTTPException)

from fastapi import HTTPException, status

raise HTTPException(
    status_code=status.HTTP_409_CONFLICT,
    detail="该项目下已存在同名角色"
)

之后 (使用自定义异常)

from app.core.exceptions import NotFoundError, ValidationError, InternalServerError

raise ValidationError("该项目下已存在同名角色")

2. 查询参数支持 camelCase

project_element_tags.py

# 之前
element_type: Optional[str] = None

# 之后
element_type: Optional[str] = Query(None, alias="elementType", description="元素类型过滤")

3. 异常映射规则

场景 之前 之后
资源不存在 HTTPException(404) NotFoundError()
参数验证失败 HTTPException(400) ValidationError()
权限不足 HTTPException(403) PermissionError()
服务器错误 HTTPException(500) InternalServerError()
唯一约束冲突 HTTPException(409) ValidationError()

修改文件列表

1. server/app/api/v1/projects.py

  • 添加自定义异常导入
  • 响应格式已使用 SuccessResponse(无需修改)
  • 查询参数已支持 camelCase(无需修改)

2. server/app/api/v1/project_resources.py

  • 添加自定义异常导入
  • 响应格式已使用 SuccessResponse(无需修改)
  • 查询参数已支持 camelCase(无需修改)

3. server/app/api/v1/project_elements.py

  • 移除 HTTPException 导入
  • 添加自定义异常导入
  • 替换角色创建异常:HTTPException(409)ValidationError()
  • 替换场景创建异常:HTTPException(409)ValidationError()
  • 替换道具创建异常:HTTPException(409)ValidationError()

4. server/app/api/v1/project_element_tags.py

  • 移除 HTTPException 导入
  • 添加自定义异常导入 (NotFoundError, ValidationError, InternalServerError)
  • 替换创建标签异常:HTTPException(400)ValidationError(), HTTPException(500)InternalServerError()
  • 替换获取标签异常:HTTPException(500)InternalServerError()
  • 替换更新标签异常:HTTPException(404)NotFoundError(), HTTPException(500)InternalServerError()
  • 替换删除标签异常:HTTPException(404)NotFoundError(), HTTPException(500)InternalServerError()
  • 替换设置默认标签异常:HTTPException(404)NotFoundError(), HTTPException(500)InternalServerError()
  • 查询参数添加 camelCase 支持:element_typeQuery(None, alias="elementType")

影响评估

前端影响

  • 无影响: 响应格式保持一致(SuccessResponse 包装)
  • 无影响: HTTP 状态码保持一致(自定义异常类已映射正确状态码)

后端影响

  • 代码质量提升: 异常处理更加统一和规范
  • 可维护性提升: 集中管理异常类型,便于后续扩展
  • 日志记录改进: 自定义异常类可以更好地集成日志系统

测试建议

1. 功能测试

  • 创建角色/场景/道具时,验证唯一约束冲突返回 400(ValidationError)
  • 访问不存在的资源时,验证返回 404(NotFoundError)
  • 无权限操作时,验证返回 403(PermissionError)

2. 接口测试

# 测试角色创建(重复名称)
curl -X POST "http://localhost:8000/api/v1/projects/{project_id}/characters" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"name": "主角", "role_type": "protagonist"}'

# 预期: HTTP 400, message: "该项目下已存在同名角色,请使用其他名称"

3. 查询参数测试(camelCase)

# 测试标签查询(使用 camelCase)
curl "http://localhost:8000/api/v1/projects/{project_id}/element-tags?elementType=character"

# 预期: 返回角色类型的标签列表

兼容性说明

  • 向后兼容: HTTP 状态码未改变
  • 向后兼容: 响应格式未改变(已使用 SuccessResponse)
  • 向后兼容: 查询参数同时支持 snake_case 和 camelCase

后续改进

  1. 考虑在全局异常处理器中统一记录异常日志
  2. ValidationError 增加结构化错误详情支持(如字段级错误)
  3. 考虑为不同业务场景创建更具体的异常子类

参考文档