Skip to content

fix: avoid crash when exporting an empty document#462

Open
SAY-5 wants to merge 1 commit intomkoskim:masterfrom
SAY-5:fix/empty-doc-export-crash
Open

fix: avoid crash when exporting an empty document#462
SAY-5 wants to merge 1 commit intomkoskim:masterfrom
SAY-5:fix/empty-doc-export-crash

Conversation

@SAY-5
Copy link
Copy Markdown

@SAY-5 SAY-5 commented Apr 28, 2026

Summary

Closes #460.

`formatTXT.file` and `formatMD.file` both interpolate
`title.toUpperCase()` directly into their template literals:

${center(title.toUpperCase()) ?? ""}      // formatTXT
# ${title.toUpperCase() ?? ""}             // formatMD

The trailing `?? ""` only fires after the method call, so when
`title` is undefined (a brand-new or otherwise empty mawe document
that has no `<title>` in its head), the call throws
`TypeError: Cannot read properties of undefined (reading 'toUpperCase')`
before the fallback can be reached.

That throw bubbles out of the Preview `flattedFormat` call, which is
why opening the Export view on an empty document crashes — it's the
TXT/MD path the issue was filed against, but every render of the
preview stack hits the same code in those two formats.

Fix

Render the title line the same way `subtitle` is already handled:
emit it only when the value is present, and skip it entirely when
missing. No layout change for documents that do have a title.

- ${center(title.toUpperCase()) ?? \"\"}
+ ${title ? center(title.toUpperCase()) : \"\"}

- # ${title.toUpperCase() ?? \"\"}
+ ${title ? \"# \" + title.toUpperCase() : \"\"}

Test plan

  • Added `test/test_export_empty.js`: loads a minimal
    `<story format="mawe" version="6">`,
    flattens it, then runs RTF, HTML, TEX1, TEX2, TXT, MD through
    `flattedFormat` with `assert.doesNotThrow`.
  • Wired into the default `npm test` runner via `test/run.mjs`.
  • Verified the test catches the regression: stashing only the
    `formatTXT.js` change makes the new test fail with the exact
    `title.toUpperCase()` TypeError described above.
  • `npm test` green with the fix applied (`test_load`,
    `test_roundtrip`, and the new `test_export_empty` all pass).

`formatTXT.file` and `formatMD.file` interpolated `title.toUpperCase()`
without first checking that `title` was defined. A freshly-created or
otherwise empty story has no `<title>` in its head, so opening Export
view (or running the TXT/MD exporter) crashed with
`TypeError: Cannot read properties of undefined (reading 'toUpperCase')`.

The trailing `?? ""` in those template literals only applied to the
result of `.toUpperCase()`, not to `title` itself, so the crash hit
before the fallback could be reached.

Now the title line is rendered the same way subtitle already is —
emitted only when present, and skipped entirely when missing.

A regression test (`test/test_export_empty.js`) loads a minimal empty
mawe document and runs every formatter (RTF, HTML, TEX1, TEX2, TXT,
MD) through `flattedFormat` to make sure none of them throws.

Closes mkoskim#460
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix: Empty document + export -> crash

1 participant