fix: models.dev UI 永久卡在 loading 态(拉取失败后标记状态并触发重绘)#282
Open
zerx-lab wants to merge 2 commits into
Open
Conversation
Fixes #145 根因: app/src/settings_view/ai_page.rs:3405 的 EnsureModelsDevLoaded Err 分支只 log::warn! 而不更新状态、不调用 ctx.notify(),导致 widget 永远无法离开 "正在拉取…" 的 loading 占位文字。 改动要点: - models_dev.rs: State 增加 last_fetch_failed: bool,新增 last_fetch_failed() / mark_fetch_failed() 公开函数,fetch 成功时重置为 false - ai_page.rs: EnsureModelsDevLoaded 与 RefreshModelsDev 的 Err 分支 调用 mark_fetch_failed() + ctx.notify() 以触发 UI 重绘 - agent_providers_widget.rs: None 分支按 last_fetch_failed() 区分 "正在加载" 与 "已失败",失败时复用 catalog-empty 文字(含"点[刷新目录]重试"指引) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MZspQZ4xceDmp3sdbEPXJP
zerx-lab
commented
Jun 25, 2026
zerx-lab
left a comment
Owner
Author
There was a problem hiding this comment.
(详见 inline comments 和下方总结 comment)
— 由 Claude Routine 自动生成;如需复评请 @ 维护者人工触发。
Generated by Claude Code
Owner
Author
Review 总结整体判断:倾向 Approve。逻辑清晰,修复路径与现有代码模式对称,无阻塞问题。 阻塞问题无。 建议
看起来不错的地方
— 由 Claude Routine 自动生成;如需复评请 @ 维护者人工触发。 Generated by Claude Code |
响应 #282 review 意见:`catalog-empty` 语义为「目录拉取成功但无内容」, 不应复用于网络拉取失败场景。新增 `settings-agent-providers-catalog-fetch-failed` 键(含 en / zh-CN / ja 三语翻译),widget 失败态改用新键。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MZspQZ4xceDmp3sdbEPXJP
Owner
Author
|
本次 webhook 触发时 head commit( Generated by Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
关联 Issue
Fixes #145
问题点(确定性描述)
根因:
app/src/settings_view/ai_page.rs:3405EnsureModelsDevLoadedaction 的Err分支既没有更新models_dev内部状态,也没有调用ctx.notify(),导致 widget 永远无法离开cached() == None→ 渲染settings-agent-providers-loading-catalog("正在拉取…")的死循环。关闭再重开设置页也无效——每次都重触发同一条失败路径,UI 永远显示 loading 占位。复现证据(引用自 Step 2)
models_dev.rs:114-120State { catalog, loaded_at }State无任何失败标志ai_page.rs:3403-3406Err(e) => log::warn!(...)agent_providers_widget.rs:1463-1478match models_dev::cached() { None => loading text }None分支无论是 loading 还是 failed 一律显示 loading 文字规模声明
models_dev::cached()等函数的已知调用方 4 处,均无需联动修改修改文件清单
app/src/ai/agent_providers/models_dev.rsState增加last_fetch_failed: bool;新增last_fetch_failed()/mark_fetch_failed();fetch 成功时重置为 falseapp/src/settings_view/ai_page.rsEnsureModelsDevLoaded与RefreshModelsDev的Err分支:调用mark_fetch_failed()+ctx.notify()app/src/settings_view/agent_providers_widget.rsNone分支按last_fetch_failed()区分"正在加载"与"已失败",失败时复用catalog-empty文字(含"点[刷新目录]重试"指引)验证
本地环境依赖缓存未就绪(容器内
cargo check因 git 依赖源不可达而失败),无法运行完整编译。代码正确性通过以下人工验证:bool字段有Default = false,#[derive(Default)]自动初始化为正确初值use crate::ai::agent_providers::models_dev;在两个 action handler 各自 arm 的块作用域内均已存在,闭包内的models_dev::mark_fetch_failed()在编译期可正确解析ctx.notify()与同文件其他Err后的ctx.notify()调用模式完全一致models_dev::last_fetch_failed()调用位于已有use crate::ai::agent_providers::models_dev;(line 1424)的作用域内影响面
models_dev::cached()的 4 处调用方(agent_providers_widget.rs:1463、ai_page.rs:3427、ai_page.rs:3458)均不受新增字段影响,无需联动改动last_fetch_failed()/mark_fetch_failed()仅作 crate 内部使用#[derive(Default)]保证新字段last_fetch_failed初值为false,与原有语义(未发生失败)一致,无 breaking changeGenerated by Claude Code