Skip to content

文档型连接连不上时弹提示框,别让"点了连接什么都没发生" - #362

Merged
joesdu merged 2 commits into
mainfrom
dev
Sep 3, 2026
Merged

文档型连接连不上时弹提示框,别让"点了连接什么都没发生"#362
joesdu merged 2 commits into
mainfrom
dev

Conversation

@joesdu

@joesdu joesdu commented Sep 3, 2026

Copy link
Copy Markdown
Owner

这个 PR 做了什么

SFTP / FTP / 插件文件系统(S3…)/ 插件工作台(Redis…)首次连接失败时,弹一扇错误提示框(标题「连接失败」,正文 = 配置名 + 具体原因),而不是只往 24px 状态栏写一行字。顺带补上三个相邻的静默口子。

为什么这么改

用户报的现象:本机没起 Redis,点开一条 127.0.0.1:6379 的 Redis 会话 —— 没有任何提示,也没有打开任何选项卡

排查下来插件那边是对的,RedisWorkspaceProvider.OpenAsync 老老实实抛了 ProtocolConnectionException。问题在这边:

catch (Exception ex)
{
    LastConnectionError = DescribeConnectionError(ex, current);
    StatusBar.Status = LastConnectionError;
    return null;          // ← 到此为止
}

SSH 的失败之所以看得见,是因为终端标签在握手之前就建出来了,失败画在标签页内的覆盖层上(设计 yxjmg),MarkConnectionFailed 一句就够。而上面这四类是连上了才有标签页 —— 失败时既没有标签页承载提示,状态栏那行字又几乎等于不存在,于是就成了"点了连接,什么都没发生"。

同一个洞在 SFTP / FTP / S3 三条路径上一模一样(它们与工作台是同一套结构),一并补了 —— 只修 Redis 会留下三条同样静默的路径。

为什么是弹框而不是"开一个失败态标签页"。 后者更贴近 yxjmg 的取向,但要为四种文档类型各造一个空壳文档 + 失败覆盖层,改动量与风险都大得多,而且这四类没有"重连"这个动作可挂。弹框是既有手法(证书信任提示、多行粘贴确认都走 MessageDialog),一次就够。

具体改动

  • MainWindowViewModel:新增 ConnectionFailureReporter 钩子(View 层挂上,手法同 InteractiveAuthenticator;未挂时退回状态栏,不影响连接流程),四条路径的失败统一走新的 ReportConnectionFailureAsync
  • MainWindow:实现那扇框。与凭据框共用同一道串行闸(_credentialPromptGate 改名 _connectPromptGate)—— 启动恢复多条会话是并发发起的(打开软件时, 恢复会话的速度很慢 #118),一扇密码框和三扇"连不上"若各管各的,照样会叠在同一个 owner 上互相争抢禁用/启用,表现为对话框点不动。
  • 三次凭据都没过、循环退出时也报一次。原来输三遍密码之后得到的是一片安静。
  • 凭据框上取消时清空 LastConnectionError —— HostSessionOpener 正是靠它为空来区分"没连上"与"人不同意"。这条与 SSH 路径原本就一致,四条文档路径漏了。
  • DescribeConnectionError:匿名连接(公开 S3 桶、没设 requirepass 的 Redis)的目标不再拼成 @127.0.0.1:6379 这种前面缺一截的样子;插件协议族的异常消息按 SDK 契约本就是面向用户的、且已带端点,原样呈现,不再套一层"连接 X 失败:"把同一个地址写两遍。

用户主动取消不弹框:凭据框上点取消、证书提示上点"不信任",都只更新状态栏 —— 那只是复述他刚做的决定。

改动类型

  • Bug 修复
  • 新功能
  • 重构(行为不变)
  • 性能优化
  • 文档
  • 构建 / 流水线
  • 其他:

怎么验证的

  • dotnet build VelaShell.slnx —— 零警告零错误
  • dotnet test VelaShell.slnx —— 全绿
  • 新增/修改的行为有对应测试
  • 界面改动已在应用里实际跑过 —— 没跑,见「补充说明」

实测环境: Windows 11 Pro 26H2 (10.0.29648) x64 / .NET 11

测试结果:

已通过! - 失败: 0,通过:    10,已跳过: 0,总计:    10 - VelaShell.Controls.Tests.dll
已通过! - 失败: 0,通过:     3,已跳过: 0,总计:     3 - VelaShell.Terminal.RenderTests.dll
已通过! - 失败: 0,通过:    55,已跳过: 0,总计:    55 - VelaShell.Presentation.Tests.dll
已通过! - 失败: 0,通过:   362,已跳过: 0,总计:   362 - VelaShell.Terminal.Tests.dll
已通过! - 失败: 0,通过:   416,已跳过: 0,总计:   416 - VelaShell.Core.Tests.dll
已通过! - 失败: 0,通过:   360,已跳过: 2,总计:   362 - VelaShell.Infrastructure.Tests.dll
已通过! - 失败: 0,通过:   983,已跳过: 2,总计:   985 - VelaShell.Tests.dll
已通过! - 失败: 0,通过:   555,已跳过: 0,总计:   555 - VelaShell.Plugin.Ai.Tests.dll

新增 WorkspaceConnectionFailureTests(4 例,VelaShell.Tests):

用例 守住什么
ConnectionRefused_ReportsTheFailure_AndOpensNoDocument 端点不可达要报到钩子上、不开标签页、LastConnectionError 与提示同文,且目标不带前置 @
WithoutAReporter_TheFailureStillLandsOnLastConnectionError 没挂钩子(headless 单测、插件代开会话)时连接流程照旧
ExhaustedAuthenticationRetries_ReportsTheLastFailure 三次凭据都没过之后,循环退出时也报一次
CancelledCredentialPrompt_ReportsNothing 取消不弹框,并且清空 LastConnectionError

同步检查

  • 新增了界面文案 → 没有新增。弹框标题复用既有的 Msg_ConnectionFailedTitle(五份 resx 都已有)
  • 改了文档 → 已另开 PR,zh/en/ 两侧都改了

补充说明

  • 「界面改动已在应用里实际跑过」这一栏我没勾。 弹框本体是三行 MessageDialog.ShowMessageAsync,与既有调用点(Main_ExportFailed 那处)同形;单测覆盖到"钩子被调用、带什么消息"为止,再往后那一段没有在真机上点过。合并前最好有人本地起一次、关掉本地 Redis 点一条 Redis 会话确认一眼。
  • 全量测试的第一轮里 VelaShell.Infrastructure.Tests 有 1 例偶发失败,单独重跑与整轮重跑都是全绿,与本改动无关(这条路径的代码没被动过)。

关联 PR(一起合)

joesdu and others added 2 commits September 3, 2026 17:24
SFTP / FTP / 插件文件系统(S3)/ 插件工作台(Redis)连不上时,失败原因只写进
24px 的状态栏就返回了 —— 而这四类**连上了才有标签页**,失败时屏幕上一无所有。
本机没起 Redis 时点开一条 Redis 会话正是这个样子:没有提示,也没有标签页。

SSH 之所以看得见,是因为终端标签在握手之前就建出来了,失败画在标签页内的覆盖层上
(设计 yxjmg)。这四类没有那个前提,所以改为弹一扇错误提示框。

- 新增 ConnectionFailureReporter 钩子(View 层挂上,手法同 InteractiveAuthenticator),
  四条路径的失败统一走 ReportConnectionFailureAsync:状态栏 + 弹框。
- 弹框与凭据框共用同一道串行闸:启动恢复多条会话是并发发起的,两类模态框叠在
  同一个 owner 上会互相争抢禁用/启用,表现为对话框点不动。
- 顺带补上三个相邻的静默口子:
  · 三次凭据都没过、循环退出时也报一次(原来输三遍密码之后是一片安静);
  · 凭据框上取消要清空 LastConnectionError —— HostSessionOpener 正是靠它区分
    "没连上"与"人不同意";
  · 匿名连接(公开 S3 桶、没设 requirepass 的 Redis)的目标不再拼成
    "@127.0.0.1:6379" 这种前面缺一截的样子。
- 插件协议族的异常消息按 SDK 契约本就是面向用户的、且已带端点,原样呈现,
  不再套一层"连接 X 失败:"把同一个地址写两遍。

用户主动取消不弹框:凭据框上点取消、证书提示上点"不信任",都只更新状态栏 ——
那只是复述他刚做的决定。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J5gfiQ8G3JfqomjRkuHmPP
…ialog

文档型连接连不上时弹提示框,别让"点了连接什么都没发生"
@joesdu
joesdu merged commit d1562c3 into main Sep 3, 2026
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