Repository navigation
[Bug] 插件 id 冲突会让整个宿主崩溃:Cannot read properties of undefined (reading 'prepare') #8792
Replies: 1 comment
我在启动路径里没有找到显式的"重复 id 拒绝"——这与你的现象相容1. 我核到的(如实说明边界)在 请补一样把这条钉死:那两个插件的 2. 建议按"坏配置不该打死宿主"这条主题提(这是它真正的分量)你这句"必须人工删掉其中一个包才能恢复"是这条报告最重的一锤:一个配置冲突让整个应用起不来、且没有自助出口。同一天有多条同主题报告:
⇒ 建议把它们并成一条诉求:"配置错误(重复 id / 不可解析 schema / 组合不一致)应当在装配期被明确拒绝并指出冲突双方,而不是崩溃或静默劣化。" 单独一条"请修这个崩溃"很容易被当成个案,写成这一类就变成可验收的原则。 3. 修法方向(供参考)最直接的是在加载期对 id 做唯一性校验:发现重复 ⇒ 同时报出两个包名与它们的来源文件,然后拒绝其中之一(fail-closed),而不是让冲突流到运行期。 4. 版本口径你未写版本。 一条边界我确认的是"在 |
Uh oh!
There was an error while loading. Please reload this page.
Summary
当同一个 profile 里存在两个
id相同的插件时,DSH 不会拒绝加载冲突的那一个,而是抛出未捕获异常并把整个宿主打崩——应用完全起不来,必须人工删掉其中一个包才能恢复。When two plugins with the same
idare present in one profile, DSH does not reject the conflicting plugin. The host process crashes with an unhandled error and the whole application becomes unusable until the user manually removes one of the packages.Environment
resources/app.asar是密封包,用户侧读不到内部package.json)~/.dsh/profiles/desktop~/.dsh/logs不存在,启动日志与崩溃日志都没有,用户侧无法自助取证Cannot read properties of undefined (reading 'prepare'),标注UNKNOWNSteps to reproduce / 复现
node_modules/的同名目录(或从别处拷来的同名包)。Expected / 期望
装载期就检测到重复 id,并带上下文报错,例如:
然后禁用其中一个、应用照常启动,失败原因在插件管理页可见。
Actual / 实际
TypeError: Cannot read properties of undefined (reading 'prepare'),发生在装载器的prepare阶段;Why I believe this is a framework-level gap / 为什么这是框架级缺陷
一个故障里叠了三个独立缺口:
id没有唯一性校验。id在装载器里是主键(用于定位 entry、解析依赖),但没有任何前置检查;冲突一直走到prepare才以undefined的形式爆出来。reading 'prepare'既没有冲突的 id,也没有两个来源路径——用户根本无法判断该删哪个包,只能一个个试。prepare阶段没有 per-entry 的 try/catch 与降级(skip + 标记 error)。补充证据(同一套装载逻辑上的另一个隐患):
cordis-plugin-include/lib/index.js:69-84—— 没有id的insert走else data.push(...insert)(第 82 行),不去重;而 bundle 层 patch 与 profile 层 patch 会 flatten 进同一份列表,因此同一个 id 被 push 两次是完全可能的,下游却没有任何一层挡得住。Suggested fixes / 建议修复(按优先级)
prepare之前校验 id 唯一性。 flatten 之后按id建索引;冲突时抛带上下文的错误(点名两个来源),并丢弃后出现的那个,让启动继续。prepare阶段 per-entry try/catch。 失败的 entry 标记为error(在插件管理页显示原因),不要向顶层抛。id、包名、解析出的绝对路径、profile 名;界面的「本轮运行失败」应可展开看到原始栈,或提供"复制诊断信息"按钮。~/.dsh/logs/(或%APPDATA%),致命错误保留crash-<时间戳>.log;界面上暴露 DSH 版本号(现在报障连版本都填不出来)。User-side workaround / 用户侧临时规避
node_modules、package.json的dependencies和dsh.profile.bundles里搜一遍包名,确认只有一个同 id 的包;insert"和"市场/pnpm 安装"两种方式装同一个插件;Rename-Item成.trash-<时间戳>比直接删更安全)后重启。本报告来自一次真实事故;事实部分来自现场与磁盘上的装载器源码,未能取得的信息(版本号、完整堆栈)已明确标注为 UNKNOWN,未作推测。
All reactions