Skip to main content

Enhanced WebSocket Debugging and Error Handling

This document describes the enhanced error handling, rate limiting, and debugging features added to the AIQlick pipeline WebSocket connection to prevent browser hangs and improve debugging capabilities.

Key Features

1. Connection State Management

The pipeline hook now provides detailed connection states:

type ConnectionState = "disconnected" | "connecting" | "connected" | "error"
  • disconnected: Initial state or clean disconnect
  • connecting: Actively attempting to connect
  • connected: Successfully connected and ready
  • error: Connection failed or encountered errors

2. Rate Limiting

Protection against rapid connection attempts:

  • Minimum interval: 3 seconds between connection attempts
  • Progressive backoff: 2s, 4s, 8s, 16s, 32s delays for reconnection
  • Max attempts: 5 attempts before stopping auto-reconnection

3. Connection Timeout Protection

Prevents browser hangs with connection timeouts:

  • Connection timeout: 15 seconds maximum for initial connection
  • Automatic cleanup: Timeouts are cleared on successful connection or errors
  • Timeout detection: Identifies when WebSocket is stuck in CONNECTING state

4. Heartbeat Mechanism

Detects connection health:

  • Ping interval: Every 30 seconds
  • Automatic detection: Identifies dropped connections
  • Background monitoring: Runs silently without affecting UI

5. Enhanced Error Reporting

Detailed error messages for different scenarios:

Network Errors

  • No internet connection detection
  • SSL/TLS security errors
  • CORS configuration issues
  • DNS resolution problems

WebSocket Close Codes

  • 1000: Normal closure (no reconnection)
  • 1001: Server going away (reconnect)
  • 1002: Protocol error (mark as error)
  • 1003: Unsupported data (mark as error)
  • 1006: Abnormal closure (network issue, reconnect)
  • 1011: Server error (mark as error)
  • 1012: Service restart (immediate reconnect)

6. Manual Reconnection

User-controlled reconnection with state reset:

const { reconnect, connectionState } = usePipeline(clientId)

// Manual reconnect resets all counters and timers
reconnect()

Usage Examples

Basic Connection Status Display

import { ConnectionStatus } from "@components/cv/ConnectionStatus"

function MyComponent() {
const { connectionState, reconnect } = useCvProcessor()

return (
<ConnectionStatus
connectionState={connectionState}
onReconnect={reconnect}
/>
)
}

Connection State Handling

function MyComponent() {
const { connectionState, isConnected, reconnect } = useCvProcessor()

const canUpload = connectionState === "connected" && isConnected
const showReconnect = connectionState === "error"
const isConnecting = connectionState === "connecting"

return (
<div>
{isConnecting && <div>Connecting to service...</div>}
{showReconnect && <button onClick={reconnect}>Reconnect</button>}
<button disabled={!canUpload}>Upload File</button>
</div>
)
}

Debugging Features

Console Logging

Enhanced logging for debugging:

[Pipeline] Connecting to: wss://pipeline.aiqlick.com/ws/pipeline/client-123 (attempt 1/5)
[Pipeline] Connected successfully
[Pipeline] Reconnecting in 4000ms (attempt 2/5)
[Pipeline] Rate limiting: waiting 1500ms before next connection attempt
[Pipeline] Connection timeout - closing WebSocket
[Pipeline] Max reconnection attempts reached. Stopping reconnection attempts.

Error Message Timestamps

All error messages include timestamps for debugging:

{
type: 'pipeline_error',
error: 'Connection timeout. The pipeline service is not responding.',
timestamp: 1640995200000
}

WebSocket State Reporting

Detailed WebSocket state information:

// Before: "WebSocket not ready (state: 1)"
// After: "WebSocket not ready (state: connecting). Cannot send message."

Preventing Browser Hangs

Connection Timeout

  • 15-second timeout prevents indefinite CONNECTING state
  • Automatic cleanup of stuck connections
  • Clear error messages when timeouts occur

Rate Limiting

  • Prevents rapid connection attempts that can overwhelm the browser
  • Exponential backoff reduces server load
  • Maximum attempt limits prevent infinite loops

Resource Cleanup

  • All timers and timeouts are properly cleared
  • WebSocket connections are cleanly closed
  • Memory leaks are prevented with proper cleanup

Background Process Management

  • Heartbeat runs in background without blocking UI
  • Non-blocking reconnection attempts
  • Graceful handling of component unmounting

Common Debugging Scenarios

1. Service Unavailable

Symptoms: Connection fails immediately Debug: Check console for DNS/network errors Solution: Verify service URL and network connectivity

2. Firewall/Proxy Issues

Symptoms: Connection timeout after 15 seconds Debug: Look for "Connection timeout" messages Solution: Check firewall rules and proxy configuration

3. SSL/Certificate Issues

Symptoms: Immediate connection error Debug: Look for "secure WebSocket from insecure page" errors Solution: Ensure HTTPS is used or configure SSL properly

4. Service Overload

Symptoms: Frequent disconnections with code 1011 Debug: Monitor close codes in console Solution: Service may need scaling or load balancing

5. Network Instability

Symptoms: Code 1006 errors, frequent reconnections Debug: Monitor reconnection patterns Solution: Check network stability, consider mobile/WiFi issues

Configuration

The enhanced connection logic uses these constants:

const maxReconnectAttempts = 5 // Maximum auto-reconnection attempts
const minConnectionInterval = 3000 // Minimum time between attempts (3s)
const connectionTimeout = 15000 // Connection timeout (15s)
const heartbeatInterval = 30000 // Heartbeat ping interval (30s)

These values are optimized for production use but can be adjusted based on specific requirements.

Testing Connection Issues

Simulate Network Issues

// In browser console, simulate offline
navigator.serviceWorker.controller.postMessage({ type: "offline" })

// Or disconnect network
window.dispatchEvent(new Event("offline"))

Test Rate Limiting

// Rapidly trigger reconnections
const { reconnect } = usePipeline("test")
for (let i = 0; i < 10; i++) {
setTimeout(() => reconnect(), i * 100)
}

Test Connection Timeout

  • Use invalid WebSocket URLs
  • Block WebSocket traffic in network tools
  • Monitor console for timeout messages

Best Practices

  1. Always provide manual reconnect: Allow users to recover from connection issues
  2. Show connection status: Keep users informed of connection state
  3. Handle graceful degradation: Disable features when disconnected
  4. Monitor error patterns: Use error messages to identify systemic issues
  5. Test edge cases: Verify behavior with network issues, timeouts, and service outages

This enhanced error handling ensures a robust, debuggable WebSocket connection that prevents browser hangs and provides clear feedback for troubleshooting.