Learn WebSocket - Error Handling & Reconnection Strategies
Episode 12 of 34

Learn WebSocket - Error Handling & Reconnection Strategies

This episode covers connection failures: the types of errors, proper handling patterns, reconnection strategies with exponential backoff, Socket.IO's built-in configuration, and recovery of state and lost messages.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Networks are never perfect. A dropped WiFi connection, a server restart, a failing VPN, or a phone switching networks — all of these break WebSocket connections. A good application does not give up when the connection drops; it retries intelligently and recovers the state.

Episode 12 covers error handling: recognizing and dealing with the various failures, and reconnection strategies: retrying with exponential backoff, limiting attempts, and ensuring no data is lost.

Types of Connection Failures

Connection failures come from many sources with different characteristics. The common failures you will encounter:

  • Network failure: host unreachable, DNS failure, or a blocking firewall.
  • Server unavailable: the server is down or still restarting.
  • Timeout: the server does not answer the handshake within a certain time.
  • Protocol error: the server sends an invalid frame.
  • Authentication failure: the token is rejected during the handshake.

Each error type needs a different response: retry for network failure, wait for server unavailability, and inform the user about auth failures.

Error Handling Patterns

Catching Errors in the Browser Client

The browser provides dedicated events for each connection phase.

JSError handlers in the browser
const ws = new WebSocket("wss://api.example.com/ws");
 
ws.onerror = (event) => {
  console.error("error WebSocket:", event.message);
};
 
ws.onclose = (event) => {
  console.log("koneksi ditutup:", event.code, event.reason);
  if (event.code !== 1000) {
    cobaKoneksiKembali();
  }
};

The onerror event tells you something went wrong, and onclose carries the close code. Code 1000 means a normal close; other codes such as 1006 (abnormal) indicate a dropped connection that needs retrying.

Errors on the Server Side

The server must also handle errors calmly, without crashing.

JSError handlers on the server
wss.on("connection", (ws) => {
  ws.on("error", (err) => {
    console.error("error koneksi:", err.message);
  });
 
  ws.on("message", (data) => {
    try {
      prosesPesan(data);
    } catch (err) {
      ws.send(JSON.stringify({ error: err.message }));
    }
  });
});

Every connection has its own error handler. Message processing is wrapped in try-catch so one corrupted message does not stop the entire process.

Reconnection Strategies

Exponential Backoff

Retrying immediately over and over will burden a server that is already struggling. The solution is to increase the delay exponentially.

JSReconnect with exponential backoff
let percobaan = 0;
const MAKS_PERCOBAAN = 5;
 
function hubungkan() {
  const jeda = Math.min(1000 * 2 ** percobaan, 30000);
 
  setTimeout(() => {
    const ws = new WebSocket("wss://api.example.com/ws");
 
    ws.onopen = () => {
      percobaan = 0;
    };
 
    ws.onclose = () => {
      percobaan += 1;
      if (percobaan <= MAKS_PEROBAAN) {
        hubungkan();
      }
    };
  }, jeda);
}

Math.min(1000 * 2 ** percobaan, 30000) produces delays of 1, 2, 4 seconds up to a 30-second cap. Every successful connection resets the counter, so a server restart does not crush the client.

Limit Attempts and Tell the User

An unbounded reconnect can last forever. Limit the number of attempts and show an honest message when giving up: after five failed attempts, present the option to reload the page. Users are more patient when told what is happening than when waiting in silence.

Reconnection in Socket.IO

Built-in Configuration

Socket.IO has automatic reconnection configurable with several options.

JSSocket.IO reconnection options
const socket = io("https://api.example.com", {
  reconnection: true,
  reconnectionAttempts: 10,
  reconnectionDelay: 1000,
  reconnectionDelayMax: 5000,
});
 
socket.on("reconnect_attempt", (attempt) => {
  console.log("percobaan ke:", attempt);
});
 
socket.on("reconnect_failed", () => {
  console.log("semua percobaan gagal");
});

reconnection: true enables automatic reconnect, reconnectionDelayMax caps the maximum delay. The reconnect_attempt and reconnect_failed events give you visibility into the process.

Manual Reconnection

For full control, turn off the built-in reconnection and manage it yourself.

JSManual reconnect
const socket = io("https://api.example.com", {
  reconnection: false,
});

reconnection: false disables the automation, and socket.connect() triggers a manual reconnect. This mode is useful when combining reconnection with specific business logic.

State Recovery

When the connection recovers, the client must resynchronize its state with the server.

JSState sync after reconnect
socket.on("connect", () => {
  socket.emit("sync:request", { dariId: idPesanTerakhir });
 
  socket.emit("presence:set", { status: "online" });
  socket.emit("room:rejoin", daftarRoom);
});

idPesanTerakhir lets the server resend missed messages. Rejoining rooms and resetting presence ensures the client returns to the correct position after a reconnect.

Closing

Episode 12 turned network failures from a disaster into a handled event: errors are recognized, reconnect happens with ever-longer delays, and state is restored after the connection returns.

Key takeaways:

  • Connection errors have different types that require different handling.
  • onerror and onclose in the browser carry the information for decision-making.
  • Exponential backoff prevents the server from being overwhelmed during downtime.
  • Reconnect attempts must be limited and communicated to the user.
  • Socket.IO ships a complete reconnection mechanism by default.
  • After a reconnect, resync rooms, presence, and missed messages.

In the next episode we cover rate limiting & throttling: token bucket and sliding window algorithms, per-user limits, and how to handle backpressure on the client and server.

Learn WebSocket - Error Handling & Reconnection Strategies | Learn WebSocket