fix(host-service): catch tunnel connect errors to prevent crash on DNS failure

Merged
KI
6mo ago
+43-34

Summary

  • When the laptop wakes from sleep and DNS hasn't recovered, the tunnel's auto-reconnect path calls JwtApiAuthProvider.getJwt() which fetches api.superset.sh. The fetch throws ENOTFOUND, the rejection escapes via void this.connect() (scheduleReconnect's setTimeout), and the host-service process crashes — orphaning every PTY.
  • The coordinator respawns the host-service on a new port, but the renderer's terminal WebSockets are still pointed at the dead port → "WebSocket closed (1006). Reconnecting…" loop until max attempts → user reports "all terminals died overnight."
  • Fix: wrap TunnelClient.connect()'s body in try/catch. Any throw (DNS failure, WebSocket constructor error, etc.) now routes through the same scheduleReconnect() path that handles normal socket-level errors.

Evidence

Reproduced in ~/.superset/host/<org>/host-service.log:

[host-service:tunnel] socket error: ErrorEvent { ... }
[host-service:tunnel] reconnecting in 1000ms (attempt 1)
node:internal/process/promises:394
    triggerUncaughtException(err, true /* fromPromise */);
[TypeError: fetch failed] {
  [cause]: Error: getaddrinfo ENOTFOUND api.superset.sh
}
Node.js v24.14.0

Followed immediately by a fresh [host-service:db] Initialized line — the coordinator-driven respawn that breaks the renderer's terminal sockets. No [host-service] unhandledRejection — staying up log was emitted, so the safety net in safety.ts didn't catch it (likely Node 24 default --unhandled-rejections=throw behavior on this path).

Test plan

  • Build host-service, kill network (sudo ifconfig en0 down or unplug Ethernet) while a terminal is open
  • Confirm host-service stays up: pgrep -fl host-service.js shows the same pid before and after
  • Confirm host-service.log shows [host-service:tunnel] connect failed: ... followed by reconnecting in Nms (attempt N) — no Node crash footer
  • Restore network, confirm tunnel reconnects (connected to relay for host ...) and existing terminal WebSockets keep working
  • Sanity: typecheck passes for @superset/host-service (verified locally)

Summary by cubic

Prevent @superset/host-service from crashing on DNS/network failures during tunnel reconnect by catching connect errors and routing them through the backoff, so terminals survive sleep.

  • Bug Fixes
    • Wrapped TunnelClient.connect() in try/catch; on any error (auth token fetch, WebSocket init), log [host-service:tunnel] connect failed: ..., clear the socket, and call scheduleReconnect().
    • Avoids host-service process crashes that orphan PTYs and cause dead-port terminal reconnect loops.

Summary by CodeRabbit

  • Bug Fixes
    • Improved tunnel connection stability: all connection failures are now properly caught, logged, and trigger automatic reconnection attempts.
    • Ensures transient errors (including token or network issues) no longer leave the tunnel in a broken state, reducing downtime and improving reliability.