Skip to content

fix(library): 文章库导入失败时透传结构化 detail,恢复粘贴模式降级提示#62

Merged
bob798 merged 1 commit into
mainfrom
fix/library-import-error-detail
Jun 1, 2026
Merged

fix(library): 文章库导入失败时透传结构化 detail,恢复粘贴模式降级提示#62
bob798 merged 1 commit into
mainfrom
fix/library-import-error-detail

Conversation

@bob798

@bob798 bob798 commented Jun 1, 2026

Copy link
Copy Markdown
Owner

现象

访问 /library,用 URL 模式导入大部分非白名单站点(知乎、Twitter、付费墙、反爬虫等)时:

  • 屏幕上看到一坨 JSON 串作为错误提示:{"error":"fetch_failed","hint":"抓取失败,请改用粘贴正文模式"}
  • 不会自动切到粘贴正文模式
  • 用户以为"无法导入内容"

根因

两条独立链路叠加:

  1. 后端正确语义app/services/library_service.py 抓取失败时返回 400 + {detail:{error:"fetch_failed", hint:"..."}},本意是让前端把用户引导到粘贴模式
  2. 前端 detail 丢失(本 PR 修复):useAuthFetch.js 拿到对象型 detailJSON.stringify 包进 new Error() 抛出。Library.vue 的友好分支检查 typeof err.detail === 'object',但 Error 没有 .detail 属性 → 永远走不到友好分支

修复

useAuthFetch.authFetchJson 在 raw 是对象时:

  • err.messageraw.hint || raw.error || JSON.stringify(raw)(更人话)
  • err.detail = raw(透传给调用方按业务字段降级)

影响面

  • 全前端只有 Library.vue 一处用 err.detail,立即拿到正确行为
  • 其余 130+ authFetchJson 调用方只读 .message,从原先的 JSON 串改成 hint || error,可读性提升、不破坏任何现有流程
  • 字符串 / 数组 / 字符串错误三条原有分支完全不动

验证

  • useAuthFetch.spec.js 9 个用例全绿(含新增 fetch_failed 用例 + 原有对象 detail 用例改写)
  • npm run build 通过
  • ✅ 本地起 uvicorn main:app 端到端跑:
    • POST /library/articles {url:"https://example.com/nonexistent..."} → 400 fetch_failed
    • 前端模拟 useAuthFetch 链路 → err.detail.error === 'fetch_failed' → 走友好分支 → 自动切 markdown 模式 + 显示 hint

不在范围

  • 抓取覆盖率本身(反爬虫站点本来 trafilatura 抓不到)— 单独 issue 跟踪是否上 headless / readability fallback
  • usePractice.spec.js 中 2 个 /bbc-eaw/episodes → /articles/episodes 重命名遗留失败(main 上已经红,不归本 PR)

Test plan

  • CI 前端单测全绿(除上述 2 个 pre-existing 失败)
  • 部署后到 /library 用一个明知抓不到的 URL(如 https://zhuanlan.zhihu.com/p/xxx),确认:
    • 提示文本是 "该页面无法自动抓取"(不再是 JSON 串)
    • 自动切换到「粘贴正文」tab
    • 下方 hint 显示 "抓取失败,请改用粘贴正文模式"

🤖 Generated with Claude Code

# 现象
/library 里粘贴反爬虫/SPA/无效 URL 导入时,后端正确返回
`{"detail":{"error":"fetch_failed","hint":"抓取失败,请改用粘贴正文模式"}}`,
但用户屏幕上看到的是一坨 JSON 串,且不会自动切到粘贴正文模式。

# 根因
authFetchJson 拿到对象型 detail 后 JSON.stringify 包进 new Error(detail)
抛出,调用方拿到的 err 只有 message(字符串),没有 .detail(对象)。
Library.vue 的友好降级分支 `typeof err.detail === 'object'` 永远 false,
fetchFailHint / 自动切 markdown 模式 / "该页面无法自动抓取" 全部走不到。

# 修复
authFetchJson 在 raw 是对象时:
  - message 取 raw.hint || raw.error || JSON.stringify(raw)(仍向后兼容)
  - 把原对象挂到 err.detail,让调用方按业务字段降级

仅 Library.vue 一处用 .detail;其余 130+ 调用方只看 .message,行为不变。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bob798 bob798 merged commit 6a15a27 into main Jun 1, 2026
1 check passed
@bob798 bob798 deleted the fix/library-import-error-detail branch June 1, 2026 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant