Phone remote: "Verbinden" does nothing after a wrong pairing code #9

Closed
opened 2026-08-26 01:54:00 +02:00 by benjamin · 1 comment
Owner

Problem

state.ws is assigned once and never cleared. The pair button does:

if (state.ws) state.ws.close(); else connect();   // index.html:589

After a rejected code the server sends {error:"bad_code"} and closes the socket immediately. By the time someone has retyped four digits, readyState is already CLOSED, and calling close() on a closed socket is a no-op — no event fires, nothing reconnects. The else connect() branch is dead for the rest of the page's life.

The only reconnect that still happens is the backoff timer from the original onclose. And retryDelay is never reset on this path — it grows by ×1.6 per failure up to 10 s (index.html:323-324), so the correct code inherits a multi-second wait.

Failure scenario

Someone mistypes the code, sees "falscher Code", types the right one, taps Verbinden — and nothing visibly happens. The connection only retries seconds later on its own, with no feedback in between. It looks broken.

Related: the code field accepts non-numeric input (the pattern attribute is inert without a surrounding <form>), and each bogus attempt burns one of only five rate-limited tries.

Suggested fix

  • Null out state.ws in onclose, or check readyState before deciding between close() and connect()
  • Reset retryDelay when the user submits a new code
  • Show a "verbinde…" state while waiting so the button feels responsive
  • Validate that the code is four digits client-side before spending an attempt

Found by multi-agent code review; verified against current app/src/main/assets/remote/index.html.

## Problem `state.ws` is assigned once and never cleared. The pair button does: ```js if (state.ws) state.ws.close(); else connect(); // index.html:589 ``` After a rejected code the server sends `{error:"bad_code"}` and closes the socket immediately. By the time someone has retyped four digits, `readyState` is already `CLOSED`, and calling `close()` on a closed socket is a no-op — no event fires, nothing reconnects. The `else connect()` branch is dead for the rest of the page's life. The only reconnect that still happens is the backoff timer from the original `onclose`. And `retryDelay` is never reset on this path — it grows by ×1.6 per failure up to 10 s (`index.html:323-324`), so the *correct* code inherits a multi-second wait. ## Failure scenario Someone mistypes the code, sees "falscher Code", types the right one, taps Verbinden — and nothing visibly happens. The connection only retries seconds later on its own, with no feedback in between. It looks broken. Related: the code field accepts non-numeric input (the `pattern` attribute is inert without a surrounding `<form>`), and each bogus attempt burns one of only five rate-limited tries. ## Suggested fix - Null out `state.ws` in `onclose`, or check `readyState` before deciding between `close()` and `connect()` - Reset `retryDelay` when the user submits a new code - Show a "verbinde…" state while waiting so the button feels responsive - Validate that the code is four digits client-side before spending an attempt Found by multi-agent code review; verified against current `app/src/main/assets/remote/index.html`.
Author
Owner

Fixed in dd612fc, shipped in v0.9.0.

  • state.ws is cleared in onclose, and the pair button now checks readyState <= 1 before choosing between close() and connect() — so a closed socket actually reconnects instead of hitting a no-op.
  • retryDelay is reset to 1000 ms when a new code is submitted, so the correct code no longer inherits the backoff from earlier mistakes.
  • The button gives feedback ("Verbinde…") instead of appearing dead while the reconnect runs.
  • The code is validated with /^[0-9]{4}$/ before it is sent, so a pasted non-numeric string no longer burns one of the five attempts.
Fixed in dd612fc, shipped in v0.9.0. - `state.ws` is cleared in `onclose`, and the pair button now checks `readyState <= 1` before choosing between `close()` and `connect()` — so a closed socket actually reconnects instead of hitting a no-op. - `retryDelay` is reset to 1000 ms when a new code is submitted, so the correct code no longer inherits the backoff from earlier mistakes. - The button gives feedback ("Verbinde…") instead of appearing dead while the reconnect runs. - The code is validated with `/^[0-9]{4}$/` before it is sent, so a pasted non-numeric string no longer burns one of the five attempts.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: be-nj/castarr#9