fix(main): support EACCES in server port fallback - #541
Merged
Conversation
Greptile SummaryThe PR standardizes API, KDS, and Server App startup around a reusable
Confidence Score: 5/5The PR appears safe to merge with no concrete blocking or independently actionable non-blocking issues identified. The bounded retry implementations consistently remove paired listeners, preserve successful startup initialization, expose the actual bound ports, and reject after exhaustion across all three servers.
|
| Filename | Overview |
|---|---|
| main/server.ts | Refactors API server binding into a one-time-listener retry loop supporting both address collisions and permission failures. |
| main/kds-server.ts | Applies the same bounded port fallback and listener lifecycle to the standalone KDS HTTP/WebSocket server. |
| main/server-app.ts | Extends the existing Server App retry loop to handle EACCES and report its runtime base port consistently. |
| tests/server-port-collision.test.ts | Expands isolated integration coverage across successful fallback, actual port reporting, health readiness, and retry exhaustion. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Create HTTP server] --> B[Listen on current port]
B -->|listening| C[Record active port]
C --> D[Initialize WebSocket services]
D --> E[Resolve startup]
B -->|EADDRINUSE or EACCES| F{10 attempts reached?}
F -->|No| G[Increment port]
G --> B
F -->|Yes| H[Reject startup]
B -->|Other error| H
Reviews (1): Last reviewed commit: "no-mistakes(document): Verify documentat..." | Re-trigger Greptile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Changed
EACCESerror handling alongsideEADDRINUSEin the port collision retry loop across the API server, KDS server, and Server App.tryListenpattern with one-time event listeners to prevent duplicate listener accumulation during retries.tests/server-port-collision.test.tswith comprehensive coverage for ephemeral ports,EADDRINUSEcollisions,EACCESerrors, and retry exhaustion across all servers.Risk Assessment
✅ Low: The changes cleanly unify port fallback handling across servers and support EACCES on Windows/Docker with appropriate regression tests.
Testing
Successfully executed targeted automated tests covering ephemeral ports, EADDRINUSE collisions, EACCES permission fallback, and 10-attempt retry exhaustion across main/server.ts, main/kds-server.ts, and main/server-app.ts, verifying full health check and websocket readiness on fallback ports.
Evidence: Server Port Collision and EACCES Fallback Test Output
[Test] Testing API server... [Server] Frontend build not found. Runnpm run build:frontendfirst. [Server] HTTP server running on http://localhost:60530 [KDS] WebSocket server setup complete [Server] KDS WebSocket running on ws://localhost:60530/kds [Server] HTTP/WebSocket server stopped ✅ API Server ephemeral port passed [Server] Frontend build not found. Runnpm run build:frontendfirst. [Server] Port 60532 in use (EADDRINUSE), trying 60533 [Server] HTTP server running on http://localhost:60533 [KDS] WebSocket server setup complete [Server] KDS WebSocket running on ws://localhost:60533/kds [Server] HTTP/WebSocket server stopped ✅ API Server EADDRINUSE collision fallback passed [Server] Frontend build not found. Runnpm run build:frontendfirst. [Server] Port 34500 in use (EACCES), trying 34501 [Server] HTTP server running on http://localhost:34501 [KDS] WebSocket server setup complete [Server] KDS WebSocket running on ws://localhost:34501/kds [Server] HTTP/WebSocket server stopped ✅ API Server EACCES fallback passed [Server] Frontend build not found. Runnpm run build:frontendfirst. [Server] Port 35000 in use (EACCES), trying 35001 [Server] Port 35001 in use (EACCES), trying 35002 [Server] Port 35002 in use (EACCES), trying 35003 [Server] Port 35003 in use (EACCES), trying 35004 [Server] Port 35004 in use (EACCES), trying 35005 [Server] Port 35005 in use (EACCES), trying 35006 [Server] Port 35006 in use (EACCES), trying 35007 [Server] Port 35007 in use (EACCES), trying 35008 [Server] Port 35008 in use (EACCES), trying 35009 [Server] Failed to bind to any port after 10 attempts starting from 35000 [Server] HTTP/WebSocket server stopped ✅ API Server retry exhaustion passed [Test] Testing KDS server... [KDS Server] Static build not found. Runnpm run build:frontendfirst. [KDS Server] Port 60536 in use (EADDRINUSE), trying 60537 [KDS Server] HTTP server running on http://localhost:60537 [KDS] WebSocket server setup complete [KDS Server] WebSocket running on ws://localhost:60537/kds [KDS Server] HTTP/WebSocket server stopped ✅ KDS Server EADDRINUSE collision fallback passed [KDS Server] Static build not found. Runnpm run build:frontendfirst. [KDS Server] Port 36500 in use (EACCES), trying 36501 [KDS Server] HTTP server running on http://localhost:36501 [KDS] WebSocket server setup complete [KDS Server] WebSocket running on ws://localhost:36501/kds [KDS Server] HTTP/WebSocket server stopped ✅ KDS Server EACCES fallback passed [KDS Server] Static build not found. Runnpm run build:frontendfirst. [KDS Server] Port 37000 in use (EACCES), trying 37001 [KDS Server] Port 37001 in use (EACCES), trying 37002 [KDS Server] Port 37002 in use (EACCES), trying 37003 [KDS Server] Port 37003 in use (EACCES), trying 37004 [KDS Server] Port 37004 in use (EACCES), trying 37005 [KDS Server] Port 37005 in use (EACCES), trying 37006 [KDS Server] Port 37006 in use (EACCES), trying 37007 [KDS Server] Port 37007 in use (EACCES), trying 37008 [KDS Server] Port 37008 in use (EACCES), trying 37009 [KDS Server] Failed to bind to any port after 10 attempts starting from 37000 [KDS Server] HTTP/WebSocket server stopped ✅ KDS Server retry exhaustion passed [Test] Testing Server App... [Server App] Static build not found. Runnpm run build:frontendfirst. [Server App] Port 60537 in use (EADDRINUSE), trying 60538 [Server App] HTTP server running on http://localhost:60538 [Server App] HTTP server stopped ✅ Server App EADDRINUSE collision fallback passed [Server App] Static build not found. Runnpm run build:frontendfirst. [Server App] Port 38500 in use (EACCES), trying 38501 [Server App] HTTP server running on http://localhost:38501 [Server App] HTTP server stopped ✅ Server App EACCES fallback passed [Server App] Static build not found. Runnpm run build:frontendfirst. [Server App] Port 39000 in use (EACCES), trying 39001 [Server App] Port 39001 in use (EACCES), trying 39002 [Server App] Port 39002 in use (EACCES), trying 39003 [Server App] Port 39003 in use (EACCES), trying 39004 [Server App] Port 39004 in use (EACCES), trying 39005 [Server App] Port 39005 in use (EACCES), trying 39006 [Server App] Port 39006 in use (EACCES), trying 39007 [Server App] Port 39007 in use (EACCES), trying 39008 [Server App] Port 39008 in use (EACCES), trying 39009 [Server App] Failed to bind to any port after 10 attempts starting from 39000 [Server App] HTTP server stopped ✅ Server App retry exhaustion passed 🎉 ALL PORT COLLISION & EACCES FALLBACK TESTS PASSED!Pipeline
Updates from git push no-mistakes
⏭️ **intent** - skipped
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
npm run test:server-port-collisionnpm run test:shutdown-lifecyclenpm run test:kds-integrationnpm run test:smoke✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.