Skip to content

Conversation

b4s36t4
Copy link
Contributor

@b4s36t4 b4s36t4 commented Sep 15, 2025

Description

Motivation

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)

How Has This Been Tested?

  • Unit Tests
  • Integration Tests
  • Manual Testing

Screenshots (if applicable)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Related Issues

Copy link
Contributor

Code Quality Reliability Error Handling Refactoring

Summary By MatterAI MatterAI logo

🔄 What Changed

This pull request updates the @hono/node-ws dependency to ^1.2.0. It introduces a new mechanism in realtimeHandlerNode.ts to explicitly wait for the outgoingWebSocket connection to be fully open before proceeding with further operations. Additionally, websocketUtils.ts has been refactored to improve WebSocket error handling by introducing a named errorListener for both incoming and outgoing connections, ensuring its proper removal on close, and gracefully handling normal WebSocket close events (code 1005).

🔍 Impact of the Change

These changes significantly enhance the reliability and robustness of the real-time API. By ensuring the upstream WebSocket connection is established before use, potential race conditions are mitigated. The improved error management, including explicit listener removal and graceful close handling, reduces the likelihood of unhandled errors and resource leaks, leading to a more stable and predictable real-time communication system.

📁 Total Files Changed

  • package.json: Updated @hono/node-ws dependency from ^1.0.4 to ^1.2.0.
  • src/handlers/realtimeHandlerNode.ts: Added logic to await the outgoingWebSocket's 'open' event.
  • src/handlers/websocketUtils.ts: Refactored error event listener and close event handling for WebSockets.

🧪 Test Added

N/A

🔒Security Vulnerabilities

N/A

Motivation

To improve the reliability and error handling of the real-time API by ensuring upstream WebSocket connections are established and managing errors more robustly.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)

How Has This Been Tested?

  • Unit Tests
  • Integration Tests
  • Manual Testing

Screenshots (if applicable)

N/A

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

totalScore: 3

Related Issues

N/A

Tip

Quality Recommendations

  1. Implement a timeout for the checkWebSocketOpen promise to prevent indefinite waiting if the upstream WebSocket fails to open.

  2. Enhance the console.error logging in errorListener to use a structured logging mechanism, providing more context and severity levels.

  3. Consider adding unit tests for the new checkWebSocketOpen logic and the errorListener's behavior, especially its removal on close.

Tanka Poem ♫

WebSockets now wait,
Open path, no more a race,
Errors handled well.
Code flows with a steady grace,
Reliability's embrace. ✨

Sequence Diagram

sequenceDiagram
    participant Client
    participant Gateway as Hono Node Server
    participant RealtimeHandler as realTimeHandlerNode
    participant WebSocketUtils as websocketUtils
    participant UpstreamAPI as Upstream WebSocket API

    Client->>Gateway: WebSocket Upgrade Request
    Gateway->>RealtimeHandler: upgradeWebSocket(realTimeHandlerNode)

    RealtimeHandler->>UpstreamAPI: new WebSocket(url)
    Note over RealtimeHandler: Creates outgoingWebSocket

    RealtimeHandler->>RealtimeHandler: checkWebSocketOpen = new Promise()
    RealtimeHandler->>UpstreamAPI: Add 'open' event listener

    UpstreamAPI-->>RealtimeHandler: 'open' event
    RealtimeHandler-->>RealtimeHandler: resolve(checkWebSocketOpen)
    RealtimeHandler->>RealtimeHandler: await checkWebSocketOpen

    RealtimeHandler->>Gateway: Return WebSocket handlers (onOpen, onMessage, onClose)

    Gateway->>WebSocketUtils: setupWebSocketListeners(incomingWebsocket, outgoingWebSocket)
    Note over WebSocketUtils: Configures error and close listeners

    WebSocketUtils->>UpstreamAPI: Add 'close' listener
    WebSocketUtils->>UpstreamAPI: Add 'error' listener (errorListener)
    WebSocketUtils->>Gateway: Add 'error' listener (errorListener)

    alt Outgoing WebSocket Error
        UpstreamAPI-->>WebSocketUtils: 'error' event (ErrorEvent)
        WebSocketUtils->>Gateway: console.error('outgoingWebSocket error', event)
        WebSocketUtils->>Gateway: server?.close()
    else Outgoing WebSocket Close
        UpstreamAPI-->>WebSocketUtils: 'close' event (event.code, event.reason)
        WebSocketUtils->>Gateway: removeEventListener('error', errorListener)
        opt Normal Close (code 1005)
            WebSocketUtils->>Gateway: server?.close()
        else Other Close
            WebSocketUtils->>Gateway: server?.close(event.code, event.reason)
        end
    end

    alt Incoming WebSocket Error
        Gateway-->>WebSocketUtils: 'error' event (ErrorEvent)
        WebSocketUtils->>Gateway: console.error('serverWebSocket error', event)
        WebSocketUtils->>UpstreamAPI: outgoingWebSocket?.close()
    end
Loading

Copy link
Contributor

@matter-code-review matter-code-review bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dependency update and WebSocket connection handling improvements with added error listener and open state check.

Skipped files
  • package-lock.json: Skipped file pattern

"@cfworker/json-schema": "^4.0.3",
"@hono/node-server": "^1.3.3",
"@hono/node-ws": "^1.0.4",
"@hono/node-ws": "^1.2.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📦 Dependency Issue

Issue: Updated @hono/node-ws from 1.0.4 to 1.2.0
Fix: Verify compatibility with existing WebSocket usage
Impact: Ensures latest bug fixes and features

Suggested change
"@hono/node-ws": "^1.2.0",
"@hono/node-ws": "^1.2.0",

Comment on lines +78 to +85
// wait for the upstream websocket to be open
const checkWebSocketOpen = new Promise((resolve) => {
outgoingWebSocket.addEventListener('open', () => {
resolve(true);
});
});

await checkWebSocketOpen;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Code Refactor

Issue: Added promise to wait for upstream WebSocket to be open
Fix: Ensures proper connection sequence before proceeding
Impact: Improves reliability of WebSocket connections

Suggested change
// wait for the upstream websocket to be open
const checkWebSocketOpen = new Promise((resolve) => {
outgoingWebSocket.addEventListener('open', () => {
resolve(true);
});
});
await checkWebSocketOpen;
// wait for the upstream websocket to be open
const checkWebSocketOpen = new Promise((resolve) => {
outgoingWebSocket.addEventListener('open', () => {
resolve(true);
});
});
await checkWebSocketOpen;

Comment on lines +23 to +26
const errorListener = (event: ErrorEvent) => {
console.error('outgoingWebSocket error: ', event);
server?.close();
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Code Refactor

Issue: Added error listener for outgoing WebSocket and proper cleanup
Fix: Centralizes error handling and removes listener on close
Impact: Prevents memory leaks and improves error handling

Suggested change
const errorListener = (event: ErrorEvent) => {
console.error('outgoingWebSocket error: ', event);
server?.close();
};
const errorListener = (event: ErrorEvent) => {
console.error('outgoingWebSocket error: ', event);
server?.close();
};
server.addEventListener('error', errorListener);

console.error('serverWebSocket error: ', event);
outgoingWebSocket?.close();
});
server.addEventListener('error', errorListener);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Code Refactor

Issue: Removed duplicate error listener and centralized it
Fix: Avoids duplicate error handling logic
Impact: Reduces code duplication and improves maintainability

Suggested change
server.addEventListener('error', errorListener);
server.addEventListener('error', errorListener);

@VisargD VisargD merged commit cf06031 into Portkey-AI:main Sep 16, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants