fix(video): reclaim outDir on createRenderJob throw + hide empty 4th highlight

Final whole-branch review (Opus) triaged two FIX items from the SDD nits
ledger; the rest ship as-is.

- render.js: a synchronous throw from createRenderJob (post-mkdtemp, not
  awaited) left an empty outDir on disk — the outer catch only reclaimed
  extractDir. Reclaim outDir too when it exists, and correct the stale
  comment that claimed the out dir was never created.
- {vertical,square}.html: the 4th highlights <li> lived in the DOM hidden
  only by JS, so a no-JS / failed-script render would show an empty bullet.
  Start it style="display:none" and reveal on populate, so an unscripted
  render shows nothing instead.

Vitest smoke (release-announcement.test.js) 4/4 green; render.js syntax
checked. Python suite untouched by this fix (JS/HTML only).
This commit is contained in:
Renn F
2026-07-06 02:38:10 +02:00
parent eac73f33ee
commit 9124c5836d
3 changed files with 11 additions and 4 deletions
@@ -24,7 +24,7 @@
<li class="highlights__item"><span class="highlights__tick"></span><span class="highlights__text">Fable-mode adopted fleet-wide</span></li> <li class="highlights__item"><span class="highlights__tick"></span><span class="highlights__text">Fable-mode adopted fleet-wide</span></li>
<li class="highlights__item"><span class="highlights__tick"></span><span class="highlights__text">FE/UX-UI design bar shipped</span></li> <li class="highlights__item"><span class="highlights__tick"></span><span class="highlights__text">FE/UX-UI design bar shipped</span></li>
<li class="highlights__item"><span class="highlights__tick"></span><span class="highlights__text">Feature spotlight goes live on X</span></li> <li class="highlights__item"><span class="highlights__tick"></span><span class="highlights__text">Feature spotlight goes live on X</span></li>
<li class="highlights__item"><span class="highlights__tick"></span><span class="highlights__text"></span></li> <li class="highlights__item" style="display:none"><span class="highlights__tick"></span><span class="highlights__text"></span></li>
</ul> </ul>
</div> </div>
@@ -68,6 +68,7 @@
if (!textEl) continue; if (!textEl) continue;
if (i < highlights.length && highlights[i]) { if (i < highlights.length && highlights[i]) {
textEl.textContent = String(highlights[i]); textEl.textContent = String(highlights[i]);
items[i].style.display = "";
} else { } else {
items[i].style.display = "none"; items[i].style.display = "none";
} }
@@ -23,7 +23,7 @@
<li class="highlights__item"><span class="highlights__tick"></span><span class="highlights__text">Fable-mode adopted fleet-wide</span></li> <li class="highlights__item"><span class="highlights__tick"></span><span class="highlights__text">Fable-mode adopted fleet-wide</span></li>
<li class="highlights__item"><span class="highlights__tick"></span><span class="highlights__text">FE/UX-UI design bar shipped</span></li> <li class="highlights__item"><span class="highlights__tick"></span><span class="highlights__text">FE/UX-UI design bar shipped</span></li>
<li class="highlights__item"><span class="highlights__tick"></span><span class="highlights__text">Feature spotlight goes live on X</span></li> <li class="highlights__item"><span class="highlights__tick"></span><span class="highlights__text">Feature spotlight goes live on X</span></li>
<li class="highlights__item"><span class="highlights__tick"></span><span class="highlights__text"></span></li> <li class="highlights__item" style="display:none"><span class="highlights__tick"></span><span class="highlights__text"></span></li>
</ul> </ul>
</div> </div>
@@ -67,6 +67,7 @@
if (!textEl) continue; if (!textEl) continue;
if (i < highlights.length && highlights[i]) { if (i < highlights.length && highlights[i]) {
textEl.textContent = String(highlights[i]); textEl.textContent = String(highlights[i]);
items[i].style.display = "";
} else { } else {
items[i].style.display = "none"; items[i].style.display = "none";
} }
+7 -2
View File
@@ -127,9 +127,14 @@ export async function renderComposition({
]), ]),
}; };
} catch (err) { } catch (err) {
// On any pre-render failure the out dir was never created — only the // Reclaim whatever temp dirs exist. outDir is created at the mkdtemp
// extract dir needs reclaiming. Re-throw so server.js maps it to 4xx/5xx. // above, so a sync throw from createRenderJob (post-mkdtemp, not
// awaited) leaves an empty outDir behind — reclaim it too. Re-throw
// so server.js maps the failure to 4xx/5xx.
await rm(extractDir, { recursive: true, force: true }).catch(() => {}); await rm(extractDir, { recursive: true, force: true }).catch(() => {});
if (outDir) {
await rm(outDir, { recursive: true, force: true }).catch(() => {});
}
throw err; throw err;
} }
} }