Skip to content

fix(respecDocWriter): show actual error instead of 'Error: undefined'#5179

Merged
marcoscaceres merged 6 commits intomainfrom
fix/error-undefined-message
Apr 15, 2026
Merged

fix(respecDocWriter): show actual error instead of 'Error: undefined'#5179
marcoscaceres merged 6 commits intomainfrom
fix/error-undefined-message

Conversation

@marcoscaceres
Copy link
Copy Markdown
Contributor

The timeout rejection in evaluateHTML rejects with a plain string, not an Error object. When caught, err.stack is undefined, producing 'Error: undefined'. Now falls back to err itself when stack is unavailable.

Closes #5080

The timeout rejection in evaluateHTML rejects with a plain string, not
an Error object. When caught, err.stack is undefined, producing the
unhelpful message 'Error: undefined'. Now falls back to err itself
when stack is unavailable.

Closes #5080
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves the fatal error message emitted by respecDocWriter during static HTML generation so that non-Error rejections (e.g., plain strings) show meaningful details instead of Error: undefined.

Changes:

  • Update generateHTML() error formatting to fall back to the caught value when err.stack is unavailable.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@marcoscaceres
Copy link
Copy Markdown
Contributor Author

evaluateHTML rejects with a plain string

@copilot, would it be possible/better to reject evaluateHTML with an actual error somehow? Then we would always have a stack.

…k trace

Agent-Logs-Url: https://github.com/speced/respec/sessions/f176c005-9bb3-483c-8784-2ca3e5ac0dff

Co-authored-by: marcoscaceres <870154+marcoscaceres@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 13, 2026

evaluateHTML rejects with a plain string

@copilot, would it be possible/better to reject evaluateHTML with an actual error somehow? Then we would always have a stack.

Fixed the root cause in b27310esetTimeout(() => reject(msg), ms) now becomes setTimeout(() => reject(new Error(msg)), ms), so evaluateHTML always rejects with a proper Error object and we always have a stack. The err.stack || err workaround in generateHTML is reverted since it's no longer needed.

@marcoscaceres marcoscaceres enabled auto-merge (squash) April 14, 2026 17:28
@marcoscaceres marcoscaceres merged commit e40e00c into main Apr 15, 2026
9 checks passed
@marcoscaceres marcoscaceres deleted the fix/error-undefined-message branch April 15, 2026 08:33
marcoscaceres added a commit that referenced this pull request Apr 15, 2026
)

The `data-cite-frag` → "adds the path and the fragment identifier to the
link" test was intermittently timing out in CI (FirefoxHeadless, Jasmine
5000ms default) because resolving `WHATWG-HTML` fell through to a live
`updateFromNetwork()` call against `api.specref.org` when IndexedDB was
cold (fresh CI runner).

## Root cause

`data-cite.js` calls `resolveRef(key)` for each `data-cite` element; on
a cache miss it falls back to `updateFromNetwork([key])`. The
`[[WHATWG-HTML]]` reference is not present in the document markup (only
as a `data-cite` attribute), so `biblio.js` never pre-fetches it —
leaving `data-cite.js` to hit the network at runtime. The sibling test
("cited fragments are overridden by cite-frag") happened to pass because
the first test's fetch populated IndexedDB before it ran.

## Fix

Pre-seed `WHATWG-HTML` via `localBiblio` inside the
`describe("data-cite-frag")` block, and pass it to `makeStandardOps` in
the two tests that reference that spec. Entries present in `localBiblio`
are explicitly excluded from specref network fetches in `biblio.js`.

```js
describe("data-cite-frag", () => {
  // Pre-seed the biblio so these tests don't depend on network-backed specref.
  const localBiblio = {
    "WHATWG-HTML": {
      href: "https://html.spec.whatwg.org/multipage/",
      title: "HTML Standard",
    },
  };

  it("adds the path and the fragment identifier to the link", async () => {
    // …
    const ops = makeStandardOps({ localBiblio }, body); // was: makeStandardOps(null, body)
    // …
  });
```

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

Create a fix for flaky Karma integration test in
#5179.

Context:
- Failing job: 71167571943 (workflow: .github/workflows/pr.yml, ref
6c5058a)
- Failure is in Karma integration tests (FirefoxHeadless) due to Jasmine
timeout (5000ms):
"Core — data-cite attribute" → "data-cite-frag" → "adds the path and the
fragment identifier to the link"
  from tests/spec/core/data-cite-spec.js.
- The test likely depends on network-backed biblio fetch via
updateFromNetwork()/resolveRef in src/core/data-cite.js, making it
flaky.

Goal:
- Harden the test to avoid flakiness by eliminating network dependency
and/or ensuring deterministic bib resolution.

Implementation guidance:
1) Prefer removing network dependency rather than just increasing
Jasmine timeouts.
2) Investigate how biblio is resolved in tests. Find existing test
utilities or fixtures that stub specref/biblio resolution.
3) For this specific test, ensure that resolving "WHATWG-HTML" does not
require network. Options:
- Pre-seed the biblio/specref cache with a minimal entry for WHATWG-HTML
(href and title) for the duration of the test.
- Mock/spy on resolveRef and/or updateFromNetwork to return
deterministic data.
   - Configure test environment to disable network updates for biblio.
4) Keep change minimal and localized to tests if possible.
5) Ensure all existing tests still pass and no global pollution (restore
stubs/mocks after test).

Files likely involved:
- tests/spec/core/data-cite-spec.js
- src/core/data-cite.js
- src/core/biblio.js (and/or spec ref resolution code)
- tests/spec/SpecHelper.js or other test helpers

Deliverable:
- A PR against speced/respec with the hardening fix.
- Include/update tests as needed.
- Provide concise explanation in PR description of why it was flaky and
how the fix makes it deterministic.

The following is the prior conversation context from the user's chat
exploration (may be truncated):

User: Please find a solution for failing job 71167571943. Use the logs,
job definition, and any referenced files where the failure occurred.
Keep your response focused on the solution and include code suggestions
when appropriate.

Assistant: The failing job **71167571943** is due to a **timeout in the
Karma integration test**:

- Failing spec: **`Core — data-cite attribute → data-cite-frag → adds
the path and the fragment identifier to the link`**
- Error: **Jasmine async timeout (5000ms)** while waiting for ReSpec to
finish (`makeRSDoc`)
- Follow-on error: `afterAll(flushIframes)` triggers `Timed out waiting
on undefined` from `tests/spec/SpecHelper.js:13` because at least one
`makeRSDoc()` promise never resolved and its timeout handler fired.

### Root cause
This particular test requires resolving external bibliography entries
(e.g., **WHATWG-HTML**) and then building the final link:

```js
data-cite="WHATWG-HTML"
data-cite-path="webappapis.html"
data-cite-frag="pass"
```

In `src/core/data-cite.js`, `run()` calls:

- `updateBiblio([...elems])` → which calls
`updateFromNetwork(missingBibEntries)` (network-backed)
- then per element calls `getLinkProps()` → which calls
`resolveRef(key)` again

If the network fetch is slow/flaky in CI (or FirefoxHeadless is slower),
`doc.respec.ready` may not resolve within **5s**, causing the Jasmine
timeout.

### Solution (make the test resilient)
Increase the timeout for this test (or for the whole `describe`) so it
can tolerate slower CI runs.

In **`tests/spec/core/data-cite-spec.js`** at the `data-cite-frag` test
(around lines 205–225 in ref
`6c5058a67ea2320b61f019eeb26257ae212a894d`), add a larger timeout:

```js
describe("data-cite-frag", () => {
  it(
    "adds the path and the fragment identifier to the link",
    async () => {
      const body = `
        <section class="informative">
          <p id="t1"><a
            data-cite="WHATWG-HTML"
            data-cite-path="webappapis.html"
            data-cite-frag="pass">inline link</a></p>
        </section>
      `;
      const ops = makeStandardOps(null, body);
      const doc = await makeRSDoc(ops);
      const a = doc.querySelector("#t1 > a");
      expect(a.textContent).toBe("inline link");
      expect(a.href).toBe(
        "https://html.spec.whatwg.org/multipage/webappapis.html#pass"
      );
      expect(doc.getElementById("bib-whatwg-html").closest("section").id).toBe(
        "informative-references"
      );
    },
    15000 // bump timeout for slower CI / network-backed biblio
  );
});
```

This is the most targeted fix (only affects the slow/flaky test).

### Optional hardening (recommended)
If you want to remove flakiness entirely, avoid relying on
network-backed biblio in this test by ensuring the needed biblio entry
is already available locally (e.g., inject a minimal biblio entry for
`WHATWG-HTML` via test setup). That would eliminate the dependency on
`updateFromNetwork()` timing, but requires a bit more refactoring of how
the test provides biblio ...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: marcoscaceres <870154+marcoscaceres@users.noreply.github.com>
Co-authored-by: Marcos Cáceres <marcosc@apple.com>
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.

Undefined error during static HTML generation

4 participants