You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug] client-connection is missing the webServer injection: every third-party rpc.handle registration fails silently
#6880
Error: cannot get property "webServer" without inject
at Fiber.<anonymous> (…/packages/client/connection/src/rpc-host.ts:179:19)
at Proxy.register (…/packages/client/connection/src/rpc-host.ts:178:18)
[probe:index] apply called (inject satisfied); {"get.loader":true,"get.tools":true,"get.skills":true,
"proxy.connection":"throw","get.connection":false,"get.webServer":false,...}
[probe:rpc] constructor: ctx.get(connection) available = false
[probe:rpc] inject callback fired; connection available = true
[probe:rpc] registering /skill-mcp via inject-callback
[probe:rpc] handle() THREW via inject-callback:
Error: cannot get property "webServer" without inject
at Fiber.<anonymous> (…/packages/client/connection/src/rpc-host.ts:179:19)
at Proxy.register (…/packages/client/connection/src/rpc-host.ts:178:18)
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
一句话
client-connection的 RPC 通道注册路径访问了它没有声明的webServer注入,导致任何第三方插件调用ctx.connection.rpc.handle()都会静默失败(无日志、无异常冒出),客户端只能看到HTTP 405。现象
第三方客户端插件(宿主半边调用
ctx.connection.rpc.handle('/foo', handler))在浏览器侧请求POST /foo/bar时得到 405,宿主日志干净无报错。同一实例实测对照:
POST /plugin-center/listInstalledPOST /api/plugin-center/listInstalled/api处理器在,但不认识该通道两条对照说明通道根本没注册,而不是路径写错或
/api未挂载。根因
packages/client/connection/src/rpc-host.ts:178-181:owner由同文件的get rpc()(rpc-host.ts:79-86)定为 Connection 服务自身的 fiber(const owner = this.ctx)。而该插件的注入声明是(
packages/client/connection/src/index.ts:69):webServer不在其中,cordis 的属性代理拒绝访问并抛错:异常发生在
owner.effect(...)的注册回调内部:通道从未注册,且不影响其它插件、不产生日志。调用方(第三方插件)通常既不try/catch也不检查handle()的返回值,所以缺陷完全静默。api-remotes的 Typert Remote 对第三方包是关闭的(显式官方./remote白名单),因此rpc.handle()是第三方插件暴露宿主能力的唯一手段——它失效等于第三方插件的宿主半边整体不可用。复现
node --import tsx/esm apps/cli/src/bin.ts web --port <port>(本地为dsh-v0.1.5-rc.2)。ctx.connection.rpc.handle('/foo', handler)。POST /foo/bar→ 405,宿主 stderr 无输出。形态差异线索
同一份插件代码(同版本):
kernel-child.bundle.mjs)dsh-web-runtime)差异在装配形态,不在插件代码。
我们已落地的绕过(供参考)
改用
connection.fetch.register()(rpc-host.ts:139-156):它只写 Connection 自己的fetchRoutes,不触碰owner.webServer。配套两点(也是排查中得到的事实):
connection服务在插件apply时尚未就绪(实测ctx.get('connection') === undefined),且ctx.plugin(P)不等待依赖,必须用ctx.inject(['connection'], cb);fetch)回退逻辑通道;浏览器侧先试新路由,收到 404 才回退(新路由未注册时/api/*是 404,根路径才是 405)。绕过后的实测:两个端点均 200,面板恢复,控制台 0 errors。
建议修法(任一)
client-connection的inject中补上webServer(若装配确实保证其可用,这是最小改动);register()内改用this.ctx.get('webServer'),取不到时显式抛错,让失败发生在插件作者能看到的位置;handle()无法注册时同步抛错,或宿主侧打一条 warn——避免同类问题再次以「405 + 无日志」的形态出现。附:探针原始输出
在插件
dist内临时插探针(console.error+handle()包try/catch)后重启捕获:(探针仅用于取证,验证后已回滚;未对 DSH 源码做任何修改。)
All reactions