fix(scripts): extract-from-douyin 异常路径全部返回业务码,杜绝 500 INTERNAL_ERROR #1963

Merged
xiaoxia merged 1 commits from fix/extract-douyin-error-handling into develop 2026-09-16 13:36:47 +08:00
Owner

问题

POST /api/v1/scripts/extract-from-douyin 在以下场景返回 500 INTERNAL_ERROR,前端无法区分业务错误:

  • 抖音短链无效(如 https://v.douyin.com/test123/)
  • 网络异常 / 视频下架
  • yt-dlp info 返回成功但文件未实际落地
  • ASR 抛非预期异常(非 ASRNotConfiguredError / ASRTranscriptionError)
  • duration 字段非数字

修复

  • yt-dlp 导入失败(容器缺依赖)→ 503 「抖音提取功能暂不可用」
  • DownloadError 细分:404/not found/unable to download/unsupported url → 400 「无法解析该抖音链接」;其它网络异常 → 502 「视频下载失败」
  • 文件未落地(isfile False 或 size=0)→ 502 「未获取到有效文件」
  • duration 非数字 → 安全降级为 0(不再抛 ValueError 冒泡成 500)
  • ASR 兜底 catch Exception → 502 「语音识别失败」
  • 最外层兜底 catch Exception → 即使有未预期异常也带具体 detail 返回(不再是通用 INTERNAL_ERROR)
  • text/duration 提前初始化,避免异常路径 UnboundLocalError

测试

  • 新增 tests/unit/test_extract_from_douyin_errors.py(8 个失败场景断言)
  • 更新 tests/unit/test_scripts_ai.py(mock os.path.isfile/getsize)
  • ✅ 全量单测 15531 passed(原 15523 + 8 新增)

顺带验证

  • AI 数字人对口型 / avatar 创建接口:POST /lipsync/jobs 和 POST /ai-avatar/render 都返回 422(缺必填字段)而不是 502,说明 DOUBAO key 恢复后数字人相关路由也已恢复
## 问题 POST /api/v1/scripts/extract-from-douyin 在以下场景返回 500 INTERNAL_ERROR,前端无法区分业务错误: - 抖音短链无效(如 https://v.douyin.com/test123/) - 网络异常 / 视频下架 - yt-dlp info 返回成功但文件未实际落地 - ASR 抛非预期异常(非 ASRNotConfiguredError / ASRTranscriptionError) - duration 字段非数字 ## 修复 - **yt-dlp 导入失败**(容器缺依赖)→ 503 「抖音提取功能暂不可用」 - **DownloadError 细分**:404/not found/unable to download/unsupported url → 400 「无法解析该抖音链接」;其它网络异常 → 502 「视频下载失败」 - **文件未落地**(isfile False 或 size=0)→ 502 「未获取到有效文件」 - **duration 非数字** → 安全降级为 0(不再抛 ValueError 冒泡成 500) - **ASR 兜底 catch Exception** → 502 「语音识别失败」 - **最外层兜底 catch Exception** → 即使有未预期异常也带具体 detail 返回(不再是通用 INTERNAL_ERROR) - text/duration 提前初始化,避免异常路径 UnboundLocalError ## 测试 - 新增 `tests/unit/test_extract_from_douyin_errors.py`(8 个失败场景断言) - 更新 `tests/unit/test_scripts_ai.py`(mock os.path.isfile/getsize) - ✅ 全量单测 15531 passed(原 15523 + 8 新增) ## 顺带验证 - AI 数字人对口型 / avatar 创建接口:POST /lipsync/jobs 和 POST /ai-avatar/render 都返回 422(缺必填字段)而不是 502,说明 DOUBAO key 恢复后数字人相关路由也已恢复
xiaoxia added 1 commit 2026-09-16 13:17:05 +08:00
fix(scripts): extract-from-douyin 异常路径全部返回业务码,杜绝 500 INTERNAL_ERROR
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m18s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m43s
AI Code Review / AI Code Review (pull_request) Successful in 6m16s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 12m6s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 10s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 36s
fca943428b
问题:POST /api/v1/scripts/extract-from-douyin 在抖音短链无效/网络异常/ASR 兜底异常等
场景下冒泡未捕获 Exception,被全局 general_exception_handler 吞成 500 INTERNAL_ERROR,
前端无法区分业务错误。

修复(apps/api/app/api/routes/scripts_ai.py):
1. yt-dlp 导入失败(缺依赖)→ 503(提示功能不可用)
2. yt_dlp.utils.DownloadError 单独捕获:
   - 含 404/not found/unable to download/unsupported url → 400「无法解析该抖音链接」
   - 其它网络/上游异常 → 502「视频下载失败」
3. 下载 info 成功但文件未落地(isfile False / size 0)→ 502「未获取到有效文件」
4. duration 非数字(TypeError/ValueError)→ 安全降级为 0
5. ASR 转写兜底 catch Exception → 502「语音识别失败」(原只 catch 两个自定义异常)
6. 最外层兜底 catch Exception → 500 但带具体 detail(不再是通用 INTERNAL_ERROR)
7. text/duration 提前初始化,避免异常路径 UnboundLocalError

测试:
- 新增 tests/unit/test_extract_from_douyin_errors.py,覆盖 8 个失败场景
- 更新 tests/unit/test_scripts_ai.py 三个成功/ASR 路径测试,mock os.path.isfile/getsize
- 全量单测 15531 passed

🚀 预览环境已部署

项目 详情
PR号 #1963
预览链接 https://pr-1963.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1963 | | 预览链接 | [https://pr-1963.preview.xiaoxiajianji.com](https://pr-1963.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
xiaoxia merged commit 57545ab694 into develop 2026-09-16 13:36:47 +08:00

🗑️ 预览环境已清理

PR #1963 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1963 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.