Skip to content

fix: reject sendMessage when the websocket reply never arrives - #254

Merged
zoe-codez merged 1 commit into
Digital-Alchemy-TS:mainfrom
jaredcat:fix/reject-missing-websocket-reply
Aug 18, 2026
Merged

zoe-codez merged 1 commit into
Digital-Alchemy-TS:mainfrom
jaredcat:fix/reject-missing-websocket-reply

Conversation

@jaredcat

@jaredcat jaredcat commented Aug 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • sendMessage waits on a Promise whose resolve is stored in waitingCallback.
  • After EXPECT_RESPONSE_AFTER (default 5s), waitForReply deleted that waiter and logged a warning, but never settled the Promise. Callers (hass.call, entity service methods, registry ops) hung forever.
  • The same happened for { type: "result", error: ... } replies: onMessageResult logged and returned without calling the waiter.

This showed up in production as a hung climate.set_preset_mode leaving an automation stuck overnight. The warning was in the logs; the Promise was still pending.

Behavior change

  • Timed-out messages now reject with InternalError code MISSING_REPLY.
  • Error results now reject with InternalError code RESULT_ERROR.
  • Successful replies are unchanged.
  • Slow integrations can still raise EXPECT_RESPONSE_AFTER (seconds).

Callers that currently fire-and-forget hass.call / sendMessage without .catch() will start seeing unhandled rejections instead of silent hangs. That is the correct default.

Test plan

  • yarn vitest run src/testing/websocket.spec.mts — resolve on result, reject on timeout, reject on error result
  • Full suite: 280 passed / 5 skipped
  • Manual: call a service against a disconnected/hung integration and confirm the Promise rejects after EXPECT_RESPONSE_AFTER instead of blocking

waitForReply dropped the waiter after EXPECT_RESPONSE_AFTER and logged a warning, but never settled the Promise. Hung Home Assistant calls (climate, ADB, etc.) could then block callers forever. Reject with MISSING_REPLY, and reject RESULT_ERROR replies the same way instead of leaving those pending too.

Co-authored-by: Cursor <cursoragent@cursor.com>
@codecov

codecov Bot commented Aug 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.15%. Comparing base (66093d0) to head (388cac2).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #254      +/-   ##
==========================================
+ Coverage   81.79%   82.15%   +0.35%     
==========================================
  Files          47       47              
  Lines        1774     1776       +2     
  Branches      197      207      +10     
==========================================
+ Hits         1451     1459       +8     
+ Misses        322      315       -7     
- Partials        1        2       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@zoe-codez

Copy link
Copy Markdown
Member

LGTM, thanks for the PR!

@zoe-codez
zoe-codez merged commit 37d737a into Digital-Alchemy-TS:main Aug 18, 2026
3 checks passed
@jaredcat
jaredcat deleted the fix/reject-missing-websocket-reply branch August 18, 2026 00:41
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.

2 participants