AIS WebSocket error handler does not trigger reconnection, causing permanent loss of AIS tracking after any network failure #46

Open
opened 2026-08-19 05:00:45 +00:00 by Jasper · 0 comments
Collaborator

Summary

The AISStream WebSocket error handler in server/utils/trackingFeed.js logs errors but never triggers a reconnect. Once the AIS socket hits an error (DNS failure, TCP reset, etc.), it stays in a broken state and will never recover without a server restart.

Problem

In server/utils/trackingFeed.js, the connectAisStream() function registers four event handlers on the AIS WebSocket: open, message, close, and error. The close handler calls scheduleAisReconnect(), but the error handler (line 218) only logs the error:

ws.on('error', (err) => {
  console.error('[trackingFeed] AISStream error:', err?.message)
})

When an error occurs, the WebSocket enters a broken state. The close event may or may not fire depending on how the error occurred. Meanwhile, refreshFeedBboxes() checks state.aisSocket?.readyState === WebSocket.OPEN and falls through to else if (!state.aisSocket). Since state.aisSocket still references the broken socket object (it is truthy), neither branch reconnects it.

Result: any AIS stream error permanently disables AIS tracking until process restart.

Proposed work

Add a call to scheduleAisReconnect() inside the ws.on('error') handler in server/utils/trackingFeed.js. The existing guard (state.stopped) and closeAisSocket() cleanup are already handled by scheduleAisReconnect(), so a single line addition is sufficient:

ws.on('error', (err) => {
  console.error('[trackingFeed] AISStream error:', err?.message)
  if (!state.stopped) scheduleAisReconnect()
})

Acceptance criteria

  • The ws.on('error') handler in server/utils/trackingFeed.js calls scheduleAisReconnect() when the socket is not stopped.
  • After an AIS WebSocket error, the next refreshFeedBboxes() call or the scheduled reconnect timer initiates a new connection attempt with exponential backoff.
  • Existing tests in test/unit/trackingFeed.spec.js (if any) still pass after the change.
## Summary The AISStream WebSocket error handler in `server/utils/trackingFeed.js` logs errors but never triggers a reconnect. Once the AIS socket hits an error (DNS failure, TCP reset, etc.), it stays in a broken state and will never recover without a server restart. ## Problem In `server/utils/trackingFeed.js`, the `connectAisStream()` function registers four event handlers on the AIS WebSocket: `open`, `message`, `close`, and `error`. The `close` handler calls `scheduleAisReconnect()`, but the `error` handler (line 218) only logs the error: ```js ws.on('error', (err) => { console.error('[trackingFeed] AISStream error:', err?.message) }) ``` When an error occurs, the WebSocket enters a broken state. The `close` event may or may not fire depending on how the error occurred. Meanwhile, `refreshFeedBboxes()` checks `state.aisSocket?.readyState === WebSocket.OPEN` and falls through to `else if (!state.aisSocket)`. Since `state.aisSocket` still references the broken socket object (it is truthy), neither branch reconnects it. Result: any AIS stream error permanently disables AIS tracking until process restart. ## Proposed work Add a call to `scheduleAisReconnect()` inside the `ws.on('error')` handler in `server/utils/trackingFeed.js`. The existing guard (`state.stopped`) and `closeAisSocket()` cleanup are already handled by `scheduleAisReconnect()`, so a single line addition is sufficient: ```js ws.on('error', (err) => { console.error('[trackingFeed] AISStream error:', err?.message) if (!state.stopped) scheduleAisReconnect() }) ``` ## Acceptance criteria - [ ] The `ws.on('error')` handler in `server/utils/trackingFeed.js` calls `scheduleAisReconnect()` when the socket is not stopped. - [ ] After an AIS WebSocket error, the next `refreshFeedBboxes()` call or the scheduled reconnect timer initiates a new connection attempt with exponential backoff. - [ ] Existing tests in `test/unit/trackingFeed.spec.js` (if any) still pass after the change. <!-- jasper-fp:13d3f83bd7cd388c -->
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: keligrubb/kestrelos#46