Skip to content

Unhandled promise rejections from uncaught background init (handleWhenReady) #11

Description

@dermotduffy

Importing the package kicks off an async init (handleWhenReady in dist/index.js) that is fire-and-forget: it is never awaited or .catch()-ed, and it self-reschedules via setTimeout. Any throw in that background chain therefore surfaces as an unhandled promise rejection in the consuming app. This happens in a normal browser, not just in tests:

  1. Floating registry fetches. In the ready handler, window.haNunjucks[registry].fetchRegistry(ha.hass) is called without await/.catch. fetchLabelRegistry does await connection.sendMessagePromise(...), so a transient WebSocket hiccup (e.g. an HA reconnect) rejects unhandled.
  2. Check/use mismatch. The readiness predicate guards with ha?.hass?.connected, but the handler then reads ha.hass unguarded. If the home-assistant element or its hass goes away in the await gap (dashboard reload/re-render), it throws.
  3. Unguarded document. Both the handler and the predicate call document.querySelector('home-assistant') with no guard, so import in any non-DOM/torn-down context (SSR, unit tests) throws document is not defined from the retry timer.

Repro

Import the module in a context where no connected <home-assistant> is present (a jsdom/node test is the simplest), then let the environment tear down. A pending handleWhenReady retry fires and throws:

ReferenceError: document is not defined
 ❯ dist/index.js  (handler)
 ❯ handleWhenReady dist/helpers.js
 ❯ Timeout._onTimeout dist/helpers.js

Suggested fix (behavior-preserving)

  • .catch() the top-level handleWhenReady(...) call and the floating fetchRegistry(...) promises.
  • Guard the DOM access (typeof document !== 'undefined') and have the handler use the same optional chaining as the predicate.
  • Optionally, expose an explicit/lazy init (or skip the global setup when hass is passed to renderTemplate) so the library is safe to import outside a live browser.

Confirmed present and identical in the latest release (1.7.6).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions