CodeNomad/packages
Dark ce77488d2f
fix(ui): add retry logic to SSE pong to improve connection resilience (#519)
## Problem

When the client receives a ping from the server, it responds with a pong
via HTTP POST. On unstable networks (mobile, WiFi with poor signal,
network switches), this POST can fail in multiple ways:

- **Hung requests**: `fetch()` never rejects, blocking retries
indefinitely
- **Network disconnection**: `Failed to fetch`
- **Brief disconnections**: transient network errors

Previously, a single missed pong would cause the server to close the SSE
connection after 45s, leaving message responses stuck in queue until the
next message triggered a reconnection.

## Solution

Three improvements to make the pong POST resilient:

### 1. Request timeout (10s)
Each pong POST is now bounded with a 10s `AbortSignal` timeout. Hung
requests fail fast instead of blocking indefinitely, allowing retries to
start before the server's stale connection sweep.

### 2. Selective retry with `isRetryableError()`
Only retries transient failures where recovery is possible:
- `AbortError` / `TimeoutError` (hung or timed-out requests)
- `Failed to fetch` (network disconnected)
- `NetworkError` (browser network errors)

Non-retryable errors like `404 Client connection not found` (permanently
closed connection) fail immediately instead of wasting retry attempts.

### 3. Exponential backoff (3 attempts, 100ms → 2000ms)
Handles burst failures gracefully without hammering the server.

## Changes

- **`packages/ui/src/lib/retry-utils.ts`** (new): Reusable retry utility
with `timeoutMs` and `shouldRetry` predicate support
- **`packages/ui/src/lib/server-events.ts`**: Updated pong handler to
use bounded timeout + selective retry

## Verification

- Build passes: `npm run build:ui` 
- Manually verified in production logs: retries now visible as `Pong
failed after retries` instead of single immediate failure
- SSE monitor log at `~/.codenomad/logs/sse-monitor.log` shows `PONG_OK`
/ `PONG_FAIL` / `STALE` events for ongoing monitoring
2026-06-08 17:20:10 +01:00
..
cloudflare Minimum version to 0.17.0 2026-06-04 21:07:53 +01:00
electron-app Bump version to 0.17.0 2026-06-04 21:05:56 +01:00
opencode-plugin Bump version to 0.17.0 2026-06-04 21:05:56 +01:00
server Bump version to 0.17.0 2026-06-04 21:05:56 +01:00
tauri-app Bump version to 0.17.0 2026-06-04 21:05:56 +01:00
ui fix(ui): add retry logic to SSE pong to improve connection resilience (#519) 2026-06-08 17:20:10 +01:00