fix(dash): [PKG-DASH-CLEANUP-01] preserve first cleanup exception

This commit is contained in:
Harvey Zhao committed 2026-09-15 15:57:04 +08:00
1 parent 1c522f181b
commit 25faf88e80
23 files changed
+49546 -147

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,71 @@
# PKG-DASH-CLEANUP-01 保留 DASH 清理的首个原始异常
来源 HEAD:`1c522f181be42f1c3fe5ce309cd42d85e58ac4dc`。
对应 API-04 异常传播、API-05 生命周期和 API-07 控件集成。
## 缺陷、结构与兼容边界
原来四处清理循环使用 `failure ||= error` 记录失败,并用 `if (failure)` 判断
是否抛出。用户通过公开 controls.update 注册的 beforeUnmount 抛出 undefined、
null、false、0、-0、空字符串或 NaN 时,这些值被吞掉,或被后续清理的 Error
覆盖。SDK off 的自定义包装抛出同类值也会受到影响。
新增私有 cleanup.ts,把菜单、SDK 订阅、整个插件的清理调度归到一个实现。
独立 failed 标记与 unknown 原值分别表示“发生异常”和“异常是什么”;继续
执行快照中其余清理,最后原样抛出第一个值。入口的 revision 检查继续在每个
菜单清理动作之前执行;SDK 绑定和菜单所有权仍先失效,防止重入及迟到回调。
八个模块的责任与维护入口在包内 ARCHITECTURE.md 同步说明。
不改公开工厂、同步 update、选项、DOM/CSS、类型及分发路径;没有新运行时依赖、
版本或锁文件变化。SDK 仍由调用方所有。异步 SDK 刷新失败继续清理并 warn;
同步 update/destroy 才沿原调用栈传播错误,未将其改成 Promise。
核心 beforeUnmount 自身的异常可阻止该控件删除。插件会清理其他菜单并传播
原值,不绕过核心回调删除这个控件,也不承诺出错后整个 ArtPlayer.destroy
仍然完成。重复插件销毁、失效回调和剩余监听器释放分别由回归覆盖。
## 复现与验证
新增六项源码回归在未修复候选上全部失败;修复后每项实际遍历七种值,用
独立 threw 标记和 Object.is 检查,区分未抛出/throw undefined、0/-0、NaN。
覆盖 update、destroy、SDK off、后续错误覆盖、兄弟资源释放和重复销毁。
浏览器首轮四项失败来自测试输入复用旧 selector 对象:核心已经在其上定义
不可重新定义的 $control_option。修正测试为传入新的 selector 对象后,仍使用
公开 controls.update 和 beforeUnmount;这次在未修复产物上四项 Chromium
回归均因异常被吞掉而失败。两份失败报告分别保留,首轮不计产品缺陷复现。
源码专项 167 项通过;加载仓库外实际安装并保留的 main/legacy/module 三种
产物后,加上源码及历史对照共 470 项通过。不是新增了 470 个独立回归。
严格包类型、定向 lint、三格式正常构建及严格工具链检查通过。
Yarn Classic 1.22.22 / Node 24.21.0;Yarn pack 后在仓库外离线安装,再冻结锁
重装并逐文件核对。5 组 TS 5.9.3/4.3.5 模块配置的正例零诊断,每组拒绝
8 项非法调用,共 40 个预期错误。脚本保留核对后的安装副本,支持随后直接
验证该份文件,而不重新构建冒充安装产物。
浏览器采用 Windows 上 Playwright 管理的 Chromium 153.0.8010.12、Firefox
155.0 和 WebKit 26.6。结果如下;没有用 Chrome 扩展连接或模拟 SDK 代替实播。
| 输入与范围 | 通过 | 跳过 |
| --- | --- | --- |
| 源码,新增真实核心回调回归 | 12 | 0 |
| 安装 main,完整受控 SDK/DOM/原生 MP4 套件 | 96 | 0 |
| 安装 legacy,同套件的候选插件场景 | 72 | 0 |
| 安装 main,真实 SDK 解码/UI、换源清理、异步错误恢复 | 24 | 12 |
| 安装 legacy,同组真实 SDK 场景 | 24 | 12 |
合计 228 项通过、24 项能力跳过,没有失败或重试;main 中额外的发布旧插件
对照不在 legacy 轮重复执行。三格式 dist、docs/compiled 与安装副本逐字节一致,
安装包 ARCHITECTURE.md 与当前包内文档也一致。根 test:dash-control/test:unit
已纳入新增回归。本轮浏览器和分发核对结果见
[机器证据](../baselines/dash-cleanup-errors-validation.json)。
真实 SDK 播放与受控 SDK 的 DOM 测试分开记录;Windows WebKit 缺失 MSE 的
真实 MPD 场景不能算播放通过。物理设备、完整安装/SDK 矩阵和发布验收仍由
PKG-DASH-05/06 负责。本轮没有推送、部署或发布。
## 回退与交付
本任务单独提交实现、测试、打包产物、文档、风险和任务状态。回退该提交会
恢复四个有缺陷的清理循环,并撤销本次回归和安装副本保留能力;不会撤销
此前 TS 迁移、SDK 自动刷新、菜单导航或 SDK 4.5.2 seek 恢复。
+6 -3
View File
@@ -2,14 +2,15 @@
测试保护真实 npm 1.1.0 的既有调用契约,以及重构前工作区的 SDK 5.x 稳定 ID 修正。
版本来源见 [发布契约](baselines/dash-control-contract.md)。02 建立基线,03 改造运行行为,
04 已把五个自有模块迁移为严格 TS 并补齐公开类型与编辑器生成;05 新增第六个 SDK 事件模块。
04 把五个自有模块迁移为严格 TS 并补齐公开类型与编辑器生成;后续增加 SDK 事件、
4.5.2 seek 恢复和清理调度,当前八个自有模块均为严格 TS。
实际模块地图与生命周期规则见 [包内架构](../packages/artplayer-plugin-dash-control/ARCHITECTURE.md)。
## 可重跑的测试
- `yarn test:dash-control`:原有 118 项与两代 SDK 各 13 项事件/清理/重入回归,共 144 项。
- `yarn test:dash-control`:当前 167 项,覆盖历史契约、两代 SDK、事件/清理/重入及原始异常。
该脚本和 `test:unit` 都保留旧测试,完整 CI 自动执行。
- `yarn test:browser test/browser/dash-control.spec.js --trace on`:84 项,两个核心、发布插件 SDK 4/
- `yarn test:browser test/browser/dash-control.spec.js --trace on`:96 项,两个核心、发布插件 SDK 4/
候选插件 SDK 4/5、两类菜单、两种选择及候选清理、Chromium/Firefox/WebKit。
浏览器套件串行运行,避免共享端口和报告覆盖。
- `yarn ci:check`:工具链、计划、lint、声明漂移、严格类型和 Node/基线测试。
@@ -19,6 +20,8 @@
TS 4.3.5/5.9.3、五种模块模式、八条非法用法及实际 npm 旧声明的消费者对照。
- `yarn test:dash-types-package`:Yarn 打包核心/DASH、工作区外离线安装与冻结锁重装,
检查五种模式、CommonJS callable/命名空间、每模式八条非法调用,并拒绝解析回工作区。
报告中的 `installedArtifacts` 保留已逐文件核对 tarball 哈希的安装副本,供后续
`ARTPLAYER_TEST_DASH` 和 `ARTPLAYER_DASH_ARTIFACT` 运行时验证。
- `yarn test:browser test/browser/dash-sdk.spec.js --trace on`:真实 npm dash.js 4.5.2/5.2.1,
本地多画质/多音轨 MPD,新旧核心/插件、外部同步 update、自动事件刷新、同 SDK 换源、
formatter 错误恢复、实际设置点击和 SDK 原生对照。目前完整定义 114 项。
+6 -4
View File
@@ -2,9 +2,9 @@
> 由 tasks.json 生成。请修改数据后运行 `node refactor/scripts/plan.mjs --write`,不要手改本表。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 268 项,范围 22 个包及工作区/示例。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 269 项,范围 22 个包及工作区/示例。
状态:todo 43 / doing 21 / blocked 0 / done 204 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 43 / doing 21 / blocked 0 / done 205 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -24,7 +24,7 @@
| artplayer-plugin-chromecast | 1.1.0 | PKG-CAST-01, PKG-CAST-02, PKG-CAST-03, PKG-CAST-04, PKG-CAST-05, PKG-CAST-06 |
| artplayer-plugin-danmuku | 5.3.0 | PKG-DANMUKU-01, PKG-DANMUKU-02, PKG-DANMUKU-03, PKG-DANMUKU-04, PKG-DANMUKU-05, PKG-DANMUKU-06, PKG-DANMUKU-07, PKG-DANMUKU-08, PKG-DANMUKU-09, PKG-DANMUKU-10, PKG-DANMUKU-11, PKG-DANMUKU-12, PKG-DANMUKU-MASK-LOAD-01 |
| artplayer-plugin-danmuku-mask | 1.1.0 | PKG-MASK-01, PKG-MASK-02, PKG-MASK-03, PKG-MASK-04, PKG-MASK-05, PKG-MASK-06, ENG-LINT-01, PKG-DANMUKU-MASK-LOAD-01 |
| artplayer-plugin-dash-control | 1.1.0 | PKG-DASH-01, PKG-DASH-02, PKG-DASH-03, PKG-DASH-04, PKG-DASH-SEEK-01, PKG-DASH-MENU-01, PKG-DASH-05, PKG-DASH-06 |
| artplayer-plugin-dash-control | 1.1.0 | PKG-DASH-01, PKG-DASH-02, PKG-DASH-03, PKG-DASH-04, PKG-DASH-SEEK-01, PKG-DASH-MENU-01, PKG-DASH-05, PKG-DASH-06, PKG-DASH-CLEANUP-01 |
| artplayer-plugin-document-pip | 1.1.0 | PKG-DPIP-01, PKG-DPIP-02, PKG-DPIP-03, PKG-DPIP-04, PKG-DPIP-05, PKG-DPIP-06 |
| artplayer-plugin-hls-control | 1.1.0 | PKG-HLS-01, PKG-HLS-02, PKG-HLS-03, PKG-HLS-04, PKG-HLS-SDK-01, PKG-HLS-05, PKG-HLS-06, PKG-HLS-PACK-01 |
| artplayer-plugin-jassub | 1.1.0 | PKG-JASSUB-01, PKG-JASSUB-02, PKG-JASSUB-03, PKG-JASSUB-04, PKG-JASSUB-05, PKG-JASSUB-06, PKG-JASSUB-07, PKG-JASSUB-08, PKG-JASSUB-09, PKG-JASSUB-10 |
@@ -222,8 +222,9 @@
| PKG-DASH-04 | artplayer-plugin-dash-control<br>迁移自有源码和公开类型 | PKG-DASH-03, ENG-04, ENG-06, CORE-07 | dash.js adapter、selector 和回调类型 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | done |
| PKG-DASH-SEEK-01 | artplayer-plugin-dash-control<br>修复 SDK 4.5.2 暂停跳转后的缓冲指标停滞 | PKG-DASH-04 | 按版本和实测空缓冲限定的指标同步、生命周期守卫及真实 SDK 旧红新绿 | 新插件在新旧核心及 Chromium/Firefox 原位置回归通过;不修改 SDK 方法/配置、媒体时间或删除缓冲;旧 SDK 原生缺陷与旧插件限制独立记录,不宣称第三方本体已修复 | H | done |
| PKG-DASH-MENU-01 | artplayer-plugin-dash-control<br>定位并修复 SDK 刷新期间设置选项不可见 | PKG-DASH-SEEK-01 | 真实 SDK 菜单点击失败根因、对应兼容修复及新旧核心回归 | 保留 legacy/旧核心/SDK5.2.1 的原失败;确定菜单在点击过程中不可见的原因;不靠 force 点击、扩大超时或重复运行覆盖问题;main/legacy 质量与音轨设置及 SDK 刷新组合通过 | H | done |
| PKG-DASH-05 | artplayer-plugin-dash-control<br>验证新旧核心和组合 | PKG-DASH-04, CORE-22, PKG-DASH-SEEK-01 | 固定 dash.js 4.5.2/5.2.1 与本地 DASH 实际清晰度/音轨、高亮、Auto 和换源组合 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | doing |
| PKG-DASH-05 | artplayer-plugin-dash-control<br>验证新旧核心和组合 | PKG-DASH-04, CORE-22, PKG-DASH-SEEK-01, PKG-DASH-CLEANUP-01 | 固定 dash.js 4.5.2/5.2.1 与本地 DASH 实际清晰度/音轨、高亮、Auto 和换源组合 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | doing |
| PKG-DASH-06 | artplayer-plugin-dash-control<br>验证分发并同步文档 | PKG-DASH-05, ENG-07, PKG-DASH-MENU-01 | dash.control.js、支持的 dash.js 版本与产物 | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录 | H | todo |
| PKG-DASH-CLEANUP-01 | artplayer-plugin-dash-control<br>保留菜单和SDK清理的首个原始异常 | PKG-DASH-04 | 集中DASH清理调度与首错传播,保留重入保护;falsy异常、真实控件beforeUnmount、分发及文档验证 | 七种falsy值不被吞掉或后续错误覆盖;后续资源释放和生命周期回归通过,不更改公开API、SDK归属或异步刷新边界 | M | done |
## 5 包迁移:artplayer-plugin-multiple-subtitles
@@ -702,3 +703,4 @@
- SITE-CONSOLE-01: [记录](console-modernization.md) [记录](changes/2026-09-15-SITE-CONSOLE-01-typescript.md) [记录](baselines/site-console01-validation.json)
- PKG-AUTO-THUMB-12: [记录](changes/2026-09-15-PKG-AUTO-THUMB-12-metadata.md) [记录](baselines/auto-thumbnail-metadata-validation.json)
- PKG-TOOL-THUMB-07: [记录](changes/2026-09-15-PKG-TOOL-THUMB-07-cleanup-errors.md) [记录](baselines/thumbnail-cleanup-errors-validation.json)
- PKG-DASH-CLEANUP-01: [记录](changes/2026-09-15-PKG-DASH-CLEANUP-01-errors.md) [记录](baselines/dash-cleanup-errors-validation.json)
+14
View File
@@ -1,5 +1,19 @@
# 进度与证据
## PKG-DASH-CLEANUP-01 清理异常与职责归一
四处清理循环改为私有 cleanup.ts,保留首个原始异常值、剩余资源释放和重入保护。
未修复源码6失败,修正测试输入后的未修复产物4项Chromium失败;首轮输入复用
导致的4项setup失败单独保留。修复后源码167通过,安装三格式与历史/源码共470通过。
source: 12通过/0跳过;main: 96通过/0跳过;legacy: 72通过/0跳过;sdk-main: 24通过/12跳过;sdk-legacy: 24通过/12跳过。
受控SDK的DOM验证与真实dash.js 4.5.2/5.2.1播放/换源/异步恢复分开记录;
Windows WebKit MSE缺失的跳过不计实际播放。5组隔离类型正例和40预期负例成立,
三格式、文档副本与安装文件字节一致。详见[记录](changes/2026-09-15-PKG-DASH-CLEANUP-01-errors.md)和[证据](baselines/dash-cleanup-errors-validation.json)。
任务完成,DASH-05继续doing;205 done、21 doing、43 todo,共269项。
无新依赖、公开类型、版本或锁文件修改;本轮没有推送、部署或发布。
## PKG-TOOL-THUMB-07 清理异常传播修复
修复cleanupAll吞掉destroy监听器抛出的falsy值、或被后续异常覆盖的兼容回归。
+1
View File
@@ -282,3 +282,4 @@
| AUTO-THUMB-METADATA-01 | resolved / 已复现 | Private metadata loading can retain its decoder indefinitely without metadata or media errors | PKG-AUTO-THUMB-12 |
| ASR-MEDIA-01 | resolved / 已复现 | ASR accepts obsolete recognition after native media error without pause | PKG-ASR-10, PKG-ASR-05 |
| THUMB-CLEANUP-01 | resolved / 已复现 | Thumbnail 清理吞掉 falsy 监听器异常或覆盖第一个异常值 | PKG-TOOL-THUMB-07, PKG-TOOL-THUMB-04 |
| DASH-CLEANUP-01 | resolved / 已复现 | DASH 菜单和 SDK 清理吞掉 falsy 异常或丢失首个错误 | PKG-DASH-CLEANUP-01, PKG-DASH-05 |
+24
View File
@@ -6629,6 +6629,30 @@
"refactor/baselines/thumbnail-cleanup-errors-validation.json"
],
"resolutionRationale": "Frozen historical destroy contracts preserve all seven falsy values; the prepatch candidate fails exception propagation and first-value ownership. Fixed source and rebuilt main/legacy pass cleanup/resource and actual browser DOM regressions. Installed artifact and type checks pass; historical defaults and WebKit media capability gaps remain outside this narrowly resolved regression."
},
{
"id": "DASH-CLEANUP-01",
"title": "DASH 菜单和 SDK 清理吞掉 falsy 异常或丢失首个错误",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"PKG-DASH-CLEANUP-01",
"PKG-DASH-05"
],
"evidence": [
"test/dash-cleanup-errors.test.js",
"test/browser/dash-control.spec.js",
"refactor/changes/2026-09-15-PKG-DASH-CLEANUP-01-errors.md",
"refactor/baselines/dash-cleanup-errors-validation.json"
],
"compatibleResolution": "共用独立失败标记的清理调度,保存并传播第一个原始值,同时完成剩余资源释放,保留重入/SDK归属及异步警告策略。",
"closureCriteria": "七种falsy值首错身份、兄弟资源释放、重入/销毁专项、真实控件回调、三格式安装和真实SDK回归有证据;设备能力缺口单独保留。",
"workspaceState": "Prepatch: six source failures and four valid Chromium failures; fixed source 167 pass, installed three formats plus source/historical 470 pass. Browser reports distinguish controlled DOM, actual SDK and Windows WebKit MSE skips.",
"resolutionEvidence": [
"refactor/changes/2026-09-15-PKG-DASH-CLEANUP-01-errors.md",
"refactor/baselines/dash-cleanup-errors-validation.json"
],
"resolutionRationale": "Corrected public beforeUnmount input reproduces swallowed values against the prepatch artifact. Separate threw and Object.is assertions cover all seven values. Rebuilt and independently installed artifacts pass lifecycle/DOM/SDK regressions; public declarations are unchanged. This resolves the cleanup defect only, not full package device/release acceptance."
}
]
}
+5
View File
@@ -38,6 +38,11 @@ async function main() {
assert.equal(fs.realpathSync(root), root, 'Installed package is a workspace link')
for (const [member, expected] of Object.entries(pkg.files))
assert.equal(hash(fs.readFileSync(path.join(root, member.slice(8)))), expected, `Installed bytes differ: ${member}`)
const retained = path.join(output, 'installed-artifacts', pkg.name)
fs.cpSync(root, retained, { recursive: true })
for (const [member, expected] of Object.entries(pkg.files))
assert.equal(hash(fs.readFileSync(path.join(retained, member.slice(8)))), expected, `Retained installed bytes differ: ${member}`)
pkg.installedArtifacts = retained
}
const matrix = []
for (const [compiler, mode] of [[ts, 'node10-commonjs'], [ts, 'nodenext-cjs'], [ts, 'nodenext-esm'], [ts, 'bundler-esm'], [compat, 'node10-commonjs']]) {
+21 -1
View File
@@ -2328,7 +2328,8 @@
"dependsOn": [
"PKG-DASH-04",
"CORE-22",
"PKG-DASH-SEEK-01"
"PKG-DASH-SEEK-01",
"PKG-DASH-CLEANUP-01"
],
"status": "doing",
"risk": "H",
@@ -5766,6 +5767,25 @@
"changes/2026-09-15-PKG-TOOL-THUMB-07-cleanup-errors.md",
"baselines/thumbnail-cleanup-errors-validation.json"
]
},
{
"id": "PKG-DASH-CLEANUP-01",
"phase": "5 包迁移:artplayer-plugin-dash-control",
"title": "保留菜单和SDK清理的首个原始异常",
"scope": [
"artplayer-plugin-dash-control"
],
"dependsOn": [
"PKG-DASH-04"
],
"status": "done",
"risk": "M",
"deliverable": "集中DASH清理调度与首错传播,保留重入保护;falsy异常、真实控件beforeUnmount、分发及文档验证",
"acceptance": "七种falsy值不被吞掉或后续错误覆盖;后续资源释放和生命周期回归通过,不更改公开API、SDK归属或异步刷新边界",
"evidence": [
"changes/2026-09-15-PKG-DASH-CLEANUP-01-errors.md",
"baselines/dash-cleanup-errors-validation.json"
]
}
]
}