Skip to content

feat: show a launch-failure dialog with error detail and log tail (issue #30) - #36

Merged
Gu-ZT merged 2 commits into
dsh-plugins:mainfrom
yukitakasama:feat/launch-error-dialog
Sep 11, 2026
Merged

Gu-ZT merged 2 commits into
dsh-plugins:mainfrom
yukitakasama:feat/launch-error-dialog

Conversation

@yukitakasama

Copy link
Copy Markdown
Contributor

Closes #30

问题 / Problem

启动实例失败时,主页只显示一条短暂的 Message.error 提示,用户无法从提示中获得具体原因,必须手动打开 logs/<实例id>.log 排查——对非技术用户极不友好。

改动 / What changed

后端 (Rust)

  • 新增 read_instance_log_tail 命令:读取实例运行日志尾部(最多 200 行,读取范围限制在文件末尾 64 KiB),缺失文件返回空而非报错;已注册进 invoke handler 与浏览器预览 mock。

前端 (Vue/TS)

  • store(launcher.ts):exited 事件(非用户主动 stopped)现在会记录 launchError(含 exit code),不再静默丢弃状态。
  • 新增 InstanceLaunchErrorDialog 组件:标题「实例启动失败」,展示错误摘要 + 关键日志尾部,底部操作「复制错误信息 / 打开完整日志 / 关闭」。
  • Home.vue:同步启动失败(前置校验 / spawn 失败)同样接入该对话框。
  • App.vue 挂载对话框;api/index.ts 封装 readInstanceLogTail;i18n 中英文案齐全。

验证 / Validation(与 CI 相同命令)

  • cargo fmt --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace ✅(91 passed)
  • pnpm build(vue-tsc + vite)✅
  • node ci/check-versions.mjs
  • node --test ci/release-notes.test.mjs / bump-version.test.mjs

@Gu-ZT Gu-ZT left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感谢 PR,功能方向与 issue #30 的诉求吻合(Rust 侧 read_instance_log_tail 实现质量很好:缺失文件返回空、64 KiB 有界读取、from_utf8_lossy 兼容 TUI 原始字节、instance_id 先校验再拼路径)。但当前前端有两个必须修复的问题,本次 request changes

阻塞项

1. [HIGH] 正常退出(exit code 0)会误弹「实例启动失败」对话框

src/stores/launcher.tsapplyStatus任何 exited 状态都调用 reportLaunchError,未检查 exit code。#33 合入后这成为可见回归:TUI 实例的正常结束方式就是用户在终端里输入 exit,PTY 子进程以 code 0 退出 → waiter 发 Exited(0) → 弹窗「实例启动失败 / exited unexpectedly (exit code: 0)」。web 实例进程自行以 0 退出同理。

修法:仅在 st.exit_code 非 null 且非 0 时报告(exit_code == null 的语义请一并考虑——waiter 拿不到退出码时传 None,对「启动失败」场景建议 null 也报告,即 st.exit_code !== 0)。

2. [MED] 浏览器预览 mock 的 switch 穿透

src/api/index.ts 中新增的 case 'read_instance_log_tail': return [] as T 插在了 open_instance_log / open_instance_directory 两个 case 标签与它们原本的 return 'C:\\…' as T 之间且没有 break——这两个既有 mock 命令现在返回 [] 而非路径字符串,原 return 成为不可达死代码。把新 case 移到原 return 之后即可。

建议一并修复(不阻塞)

  • 连续两次失败时日志尾部不刷新:dialog watch 的是 visible!!launchError 的 computed),对话框已打开时第二次失败不会重新触发 watch,摘要是新错误但日志尾部还是上一次的。改为 watch store.launchError
  • 日志冲刷竞态:waiter 发 Exited 时 stdout/stderr reader 可能还没把最后几行崩溃日志写进文件,对话框打开即读尾部可能缺最后几行。可加短延迟或重读一次;
  • Home.vue catch 里的 else Message.error 分支不可达(onStart 在未选实例时已 early-return)——可顺手删掉;
  • 两个新文件末尾缺换行符;read_tail 没有单元测试(非阻塞,建议补一个有界读取/缺失文件/尾行丢弃用例)。

其他

  • 分支基于 #34 合入前的 main,与当前 main 有一个 src/stores/launcher.ts 冲突(externalslaunchError 字段位置相邻,保留两者即可),rebase 后 CI 才能跑起来;
  • i18n 双语言已验证齐全一致 ✅;cargo fmt --checkcargo test --lib(91 passed)在 PR 分支上验证通过 ✅。

修好 1、2 并 rebase 后即可合入。

yukitakasama and others added 2 commits September 11, 2026 11:31
…sue dsh-plugins#30)

Startup failures currently surface only as a transient Message.error
toast, forcing users to hunt through logs/<instance_id>.log manually.

New behavior:
- backend: read_instance_log_tail command returns the last lines of an
  instance's runtime log (bounded to the final 64 KiB), registered in
  the invoke handler and the browser-preview mock;
- store: an unexpected 'exited' status (distinct from user-initiated
  'stopped') records a launchError with the exit code;
- frontend: InstanceLaunchErrorDialog shows the failure summary plus the
  log tail, with Copy error info / Open full log / Close actions;
  sync start failures from Home.vue route into the same dialog;
- i18n: zh-CN and en-US keys for the dialog.
- 仅在退出码非 0(或缺失)时报告启动失败,TUI 终端 exit 等正常退出(code 0)不再误弹对话框
- 修复浏览器预览 mock 的 switch 穿透:open_instance_log/open_instance_directory 恢复返回路径字符串
- 对话框改 watch launchError 本体,二次失败时日志尾部随之刷新;读取前延迟 350ms 并在 800ms 后重读一次,缓解日志冲刷竞态
- 删除 Home.vue 不可达的 else 分支;组件文件补末尾换行
- 新增 read_tail 单元测试:缺失/空文件、尾行截取与末尾换行、64 KiB 有界读取
@Gu-ZT
Gu-ZT force-pushed the feat/launch-error-dialog branch from 33ea65a to ae375f2 Compare September 11, 2026 03:39
@Gu-ZT
Gu-ZT merged commit 3a542dc into dsh-plugins:main Sep 11, 2026
8 checks passed
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.

[Feature] 启动实例失败时弹出报错对话框,展示错误详情与日志

2 participants