issue: Playwright loader logs an uncaught TargetClosedError traceback when a page closes with subrequests in flight

该报错发生在 Open WebUI 使用 Playwright 加载网页时,页面关闭瞬间仍有子请求(如 Cloudflare Turnstile 挑战)在途,导致拦截器清理阶段抛出未被捕获的 TargetClosedError 回溯。优先排查是否在页面清理时调用了 page.unroute_all(

快速结论:该报错发生在 Open WebUI 使用 Playwright 加载网页时,页面关闭瞬间仍有子请求(如 Cloudflare Turnstile 挑战)在途,导致拦截器清理阶段抛出未被捕获的 TargetClosedError 回溯。优先排查是否在页面清理时调用了 page.unroute_all(behavior='ignoreErrors')

适用环境:Open WebUI dev 分支或构建版本(Issue 中提及 7229fac0c01f4282),Docker 安装,Linux 系统,本地 Chromium(未设置 PLAYWRIGHT_WS_URL),Web 搜索启用 searxng 且加载引擎为 Playwright。

最快修复方案:暂无确认已在主分支合并的一步修复方案;但 Issue 中给出了经验证的补丁方案(对应 PR #29325):在 SafePlaywrightURLLoader 的页面生命周期中,于 finally 块内调用 await page.unroute_all(behavior='ignoreErrors')(同步路径则为 page.unroute_all(behavior='ignoreErrors')),确保清理时不因在途子请求抛错。

注意事项:该方案可优先尝试,但 Issue 中注明 PR 创建当时受仓库贡献者限制,可能尚未合入主线或后续有代码变动;此为日志噪音修复,不影响搜索结果,但若合并后有格式调整需重新验证。

问题场景

用户在使用 Open WebUI 的 Web 搜索功能时,搜索引�擎配置为 searxng,网页加载引擎配置为 Playwright(本地 Chromium)。在聊天中执行网页搜索,当搜索结果包含受 Cloudflare 保护的站点时,该页面会持续发出 Turnstile 挑战子请求;此时若加载器关闭页面,后端日志会出现一长串未捕获的 TargetClosedError 回溯,伴随一行 DEBUG 日志“Playwright loader could not fetch”。该现象不影响搜索功能,但会污染日志、干扰排障。

报错原文

2026-08-20 22:49:11.379 | DEBUG    | open_webui.retrieval.web.utils:_intercept_navigation:796 - Playwright loader could not fetch https://challenges.cloudflare.com/cdn-cgi/challenge-platform/h/g/turnstile/f/av0/rch/r7xmi/0x4AAAAAAADnPIDROrmt1Wwj/light/fbE/new/normal?lang=auto: 
Error occurred in event listener
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/playwright/_impl/_helper.py", line 428, in handle
    return await self._handle_internal(route)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/playwright/_impl/_helper.py", line 469, in _handle_internal
    await asyncio.ensure_future(coro_or_future)
...

原因分析

可能原因:SafePlaywrightURLLoader 的页面拦截器 _intercept_navigation(或同步版本 _intercept_navigation_sync)在页面关闭后,其挂在 route 上的异步任务仍在处理在途子请求。当页面被 async with/with 块关闭时,在途请求因页面关闭而失败,随后 except 块调用 await route.abort(),但此时页面已关闭,route.abort() 再次抛错,该异常未被捕获,被 Playwright 以“Error occurred in event listener”形式打印为完整回溯。本质上属于清理阶段的二次异常,属于资源生命周期管理问题,而非逻辑功能错误。

环境排查

  • Open WebUI 版本:此问题在 dev 分支复现(Issue 提及 7229fac0c),后在 main 分支 01f4282 确认存在。
  • 安装方式:Docker。
  • 操作系统:Linux。
  • Playwright 引擎:本地 Chromium,未设置 PLAYWRIGHT_WS_URL 环境变量。
  • Web 搜索配置:启用 searxng 作为搜索引�擎,Playwright 为 web loader 引擎。
  • Python 版本:日志显示 python3.11

解决步骤

  1. 确认当前安装的 Open WebUI 是否已包含上述修复(可检查 open_webui/retrieval/web/utils.py_intercept_navigation 相关代码,观察是否已有 page.unroute_all(behavior='ignoreErrors') 调用)。
  2. 若未包含,可在 SafePlaywrightURLLoader 中定位页面创建与关闭逻辑(async 路径约在 utils.py:664-693,同步路径约在 633-662,行号可能因版本漂移)。
  3. 在页面生命周期中添加清理逻辑:于 try/finallyfinally 块中,在页面关闭之前执行 await page.unroute_all(behavior='ignoreErrors')(异步路径)或 page.unroute_all(behavior='ignoreErrors')(同步路径),确保 goto()/内容提取成功、失败或超时时均能生效。
  4. 修改完成后重新构建或重启服务,进行网页搜索复测。

验证方法

使用包含 Cloudflare 保护站点的搜索词执行网页搜索,观察后端日志:若修复成功,应仅出现一行 DEBUG 日志“Playwright loader could not fetch”,不再跟随“Error occurred in event listener”的完整回溯;同时确认搜索结果不受影响。

参考来源

open-webui/open-webui #28869

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 22308

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注