🐛 修复消息层三个隐性运行时问题:广播 lastError 未检查、SW→offscreen 未就绪竞态、offscreen 创建失败永久卡死#1581
Open
cyfung1031 wants to merge 3 commits into
Open
🐛 修复消息层三个隐性运行时问题:广播 lastError 未检查、SW→offscreen 未就绪竞态、offscreen 创建失败永久卡死#1581cyfung1031 wants to merge 3 commits into
cyfung1031 wants to merge 3 commits into
Conversation
广播为 fire-and-forget,其他上下文(offscreen/popup/options)可能不存在或不回应; 不传回调时 MV3 的 chrome.runtime.sendMessage 返回的 Promise 会产生 unhandled rejection。 现传入回调并读取 chrome.runtime.lastError,无接收方等正常情况仅记录 trace。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ServiceWorkerMessageSend 此前用 clients.matchAll() 单次查找并以 this.target! 直接发送: SW 启动早于 offscreen 文档创建完成时 target 为 undefined,抛出 TypeError: Cannot read properties of undefined (reading 'postMessage'),消息静默丢失。 现改为轮询等待 offscreen 客户端出现(上限 30s),超时以可诊断错误拒绝; 并在收到来自 offscreen 的消息时刷新 target 引用,避免持有已失效的旧 Client。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
setupOffscreenDocument 的 creating latch 在 createDocument 拒绝后停留在 rejected 状态: 后台/定时脚本沙箱在本次 SW 生命周期内永远无法建立,且产生 unhandled rejection。 抽出为可测试的 offscreen_setup 模块:创建失败按退避重试(500ms/1s/2s), 与存在性检查间的 TOCTOU 竞态(文档实际已存在)视为成功, 持续失败时重置 latch 允许后续调用重新尝试。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Member
|
这是AI检查出来的吗?虽然看起来有道理,但是没有确定明确的问题,感觉不做改动最好,AI很喜欢做无意义的兜底 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist / 检查清单
Description / 描述
本 PR 修复消息层(SW ↔ offscreen / 跨上下文广播)中三个现有 vitest / e2e 均无法暴露的隐性运行时问题。每个问题均先补充失败测试再修复(TDD),共新增 12 个单元测试。
问题 1:
MessageQueue.publish未检查chrome.runtime.lastError现象:广播消息(
enableScripts、valueUpdate等)在无其他上下文存活时产生Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.;MV3 下不传回调时chrome.runtime.sendMessage返回 Promise,直接变成 unhandled rejection。Firefox MV3(事件页、无 offscreen 文档)下后台每次广播都会触发;Chrome 在 SW 启动早于 offscreen 创建的窗口期同样会触发。根因:
packages/message/message_queue.ts的publish()以 fire-and-forget 方式调用chrome.runtime.sendMessage且不传回调,lastError永远无人读取。项目自有 ESLint 规则require-last-error-check只能约束"有回调但未检查"的形态,无回调的形态是盲区。修复:传入回调并读取
chrome.runtime.lastError;无接收方属于广播的正常情况,仅记录 trace 日志,不再污染控制台/产生 unhandled rejection。问题 2:SW→offscreen 消息在 offscreen 客户端未就绪时崩溃(消息静默丢失)
现象:SW 启动后、offscreen 文档创建完成前,任何经
ServiceWorkerMessageSend发往 offscreen 的消息(如runtime/valueUpdate、runScript)抛出TypeError: Cannot read properties of undefined (reading 'postMessage'),消息静默丢失且无可诊断信息。根因:
packages/message/window_message.ts的init()只做一次clients.matchAll()查找,查不到时this.target为undefined,connect()/sendMessage()用非空断言this.target!直接发送。另外 target 一旦缓存永不刷新,offscreen 重建后旧Client引用已失效。修复:
sendMessage的 Promise 链)能正常捕获。source(即当前有效客户端)刷新 target,并校验source.url必须等于 offscreen 文档 URL,防止其他页面污染 target。问题 3:offscreen 文档创建一次失败后永久卡死,直至 SW 重启
现象:
chrome.offscreen.createDocument一旦拒绝(启动资源压力、与关闭中的文档竞态出现 "Only a single offscreen document may be created" 等暂时性失败),本次 SW 生命周期内 offscreen 环境永远无法建立——后台脚本、定时脚本、沙箱全部失效,且伴随 unhandled rejection。根因:
src/service_worker.ts中creatinglatch 在 Promise 拒绝后停留在 rejected 状态且永不重置;main()对setupOffscreenDocument()也没有任何错误处理。修复:抽出为可独立测试的
src/app/service/service_worker/offscreen_setup.ts模块:false并重置 latch,后续调用可重新尝试;不再产生 unhandled rejection;chrome.offscreen)行为不变。测试 / Test results
packages/message/message_queue.test.ts:publish 必须传回调并在回调中读取 lastError;packages/message/window_message.test.ts:客户端未出现时等待后发送、始终不可用时描述性拒绝、来源刷新 target、非 offscreen 来源不污染 target;src/app/service/service_worker/offscreen_setup.test.ts:已存在跳过创建、并发共享、TOCTOU 视为成功、退避重试、持续失败后 latch 重置、Firefox 降级。vitest run294 文件 / 3142 用例全部通过。pnpm run typecheck、ESLint、pnpm run build(Rspack 生产构建)通过。background-script.spec.ts(offscreen 路径)、gm-api.spec.ts、popup.spec.ts全部通过。Screenshots / 截图
无 UI 变更 / No UI changes.
🤖 Generated with Claude Code