0.1.5-rc.1/rc.2:调用 connection.rpc.handle() 的插件通道静默失效(405) #6337
Replies: 2 comments 2 replies
|
对着源码核了一遍,你定位的机制完全成立。补两点你可能没展开的。 1. 同一个包里就有一处正解可以直接对照
ctx.inject(['webServer'], (webCtx) => { // :119
...
webCtx.effect(() => webCtx.webServer.register(route), ...) // :138
})而 const owner = this.ctx // :80
handle: (channel, handler) => this.register(owner, channel, handler) // :82
...
return owner.effect(() => owner.webServer.register(route), ...) // :178-179这个插件的 2. 上游仍未修
你说的「单测在根上下文调用所以 CI 测不到」也对得上: 顺带:题面里说「就算把 |
|
这个和 #6227 是同一个根因。那边 wsxwj123 已经在一个真实 profile 上验证过修复方案,覆盖了 4 个 rpc.handle() 消费者(dsh-automation、dsh-appearance-gallery、dsh-session-manager、dsh-turn-scrubber),不是简单打补丁,而是让 connection 插件在自己的 apply() 里,把已经注入了 webServer 的 webCtx 通过新加的 attachWebContext() 方法保存下来,register() 优先用这个保存的上下文去拿 webServer,同时依然用 owner.effect() 包一层,这样通道的生命周期还是绑定在调用方插件上,不会绑定到 connection 自己身上,也不会影响 headless/tui 这种本来就没有 webServer 的部署。完整 diff 和 fork 分支在这里: https://github.com/wsxwj123/deepseek-harness/tree/fix/client-connection-rpc-handle-webcontext 建议把这个帖子也链接到 #6227 里,多一个独立复现对推动正式修复会有帮助。 |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
connection.rpc.handle() 在提供方影子上下文挂载路由,导致 web 路由注册时报“无法获取属性 webServer,未完成注入”
现象
在 web 部署中,插件调用
connection.rpc.handle(channel, handler)时会同步抛出:通道永远不会完成注册。浏览器请求不会命中该 RPC 路由,而是落到静态资源兜底逻辑,返回 405 状态码。
已在 dsh-mnemon(
/dsh-mnemon-read/*、-settings/*、-view/*)中复现。原因
HostConnectionService.register()使用:挂载路由,其中
owner = this.ctx。在服务方法内部,这个上下文是提供方
client-connection的影子上下文,不是调用方插件上下文;它的协程(fiber)并不持有webServer,因此 cordis 的依赖遍历逻辑抛出异常。就算把
webServer添加到注册方的注入列表也没用 —— 依赖遍历是从提供方影子上下文开始的。而单元测试是在根上下文调用,复现不了这个问题,所以 CI 检测不到。同包对照证据
packages/client/connection/src/index.ts内置的/api路由用的是派生上下文:而
rpc-host.ts里handle()走的是服务自身的this.ctx:connection 插件自身的
inject只有['credentials'],webServer是靠嵌套ctx.inject拿到webCtx才可见的 —— 所以this.ctx上没有它。同一个包、同一个动作,一处用派生上下文、一处用自身上下文,这大概就是它一直没被发现的原因。
上游状态与 CI 盲区
origin/master = c291e7961a(2026-09-10)上这几处都还在,最新 tag 仍是dsh-v0.1.5-rc.2,所以 rc.2 也一样中招。tests/node-half.host.spec.ts用fakeHttpServer把假webServer注进去,测试上下文里connection和webServer同在,owner.webServer自然解析得到。因此单测在根上下文/假 webServer 下无法复现真实部署路径,CI 检测不到。最小复现代码(web 环境)
对
/probe-rpc/x发起 POST 请求 → 返回 405(路由从未注册成功)。可选修复方案
1. 部署层面
在
packages/bundle/web-app/cordis.patch.yml的connection配置项中添加webServer:第三方插件目前只能靠自己打补丁来实现这个效果,该方案会直接覆盖这一行完整的注入数组。
2. 服务代码层面
不依赖注册方的依赖注入,直接获取 webServer。例如在
HostConnectionService.register()中使用ctx.get('webServer');如果部署环境没有挂载 webServer,则直接明确抛出错误。3. 更完整的修复方向(相关讨论中提出)
让 connection 插件在自己的
apply()里,把已经注入了webServer的webCtx通过新加的attachWebContext()方法保存下来;register()优先用这个保存的上下文去拿webServer,同时依然用owner.effect()包一层。这样通道的生命周期还是绑定在调用方插件上,不会绑定到 connection 自己身上,也不会影响 headless/tui 这种本来就没有
webServer的部署。完整 diff 和 fork 分支:
相关讨论
deepseek-harness discussion [Bug] dsh-client-connection@0.1.5-rc.1 fix(client-connection): register() resolves webServer without inject, breaking every rpc.handle() consumer #6227:
[Bug] dsh-client-connection@0.1.5-rc.1 fix(client-connection): register() resolves webServer without inject, breaking every rpc.handle() consumer #6227
wsxwj123 fork 修复分支:
https://github.com/wsxwj123/deepseek-harness/tree/fix/client-connection-rpc-handle-webcontext
All reactions