From a5ede237f0e4dc2d9ce4aee33dd3e655e6bb32a9 Mon Sep 17 00:00:00 2001 From: unraid Date: Mon, 27 Apr 2026 16:40:48 +0800 Subject: [PATCH] docs: clarify UDS peer socket ownership CodeRabbit's #375 pass found that connectToPeer now correctly hands socket errors to the caller, but the JSDoc needed to spell out that contract. The lifecycle test also uses a less brittle post-connect timeout so slow CI does not turn the ownership check into a connection-speed race. Constraint: The raw socket API intentionally detaches its internal listener after successful connect so caller-owned errors are not swallowed. Rejected: Keep the test timeout at 50ms | it tests scheduler speed instead of socket lifecycle ownership. Confidence: high Scope-risk: narrow Directive: connectToPeer callers must attach their own error listener immediately after awaiting the socket. Tested: bun test src/utils/__tests__/udsMessaging.test.ts Tested: bunx tsc --noEmit --pretty false Tested: bun run lint Tested: git diff --check Tested: bun run test:all Not-tested: GitHub-hosted CodeRabbit refresh until pushed. --- src/utils/__tests__/udsMessaging.test.ts | 2 +- src/utils/udsClient.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/utils/__tests__/udsMessaging.test.ts b/src/utils/__tests__/udsMessaging.test.ts index f2c8c3ce2..a4c49cee3 100644 --- a/src/utils/__tests__/udsMessaging.test.ts +++ b/src/utils/__tests__/udsMessaging.test.ts @@ -340,7 +340,7 @@ describe('UDS inbox retention', () => { let client: Socket | undefined try { const { connectToPeer } = await import('../udsClient.js') - client = await connectToPeer(path, 50) + client = await connectToPeer(path, 1000) await new Promise(resolve => setTimeout(resolve, 100)) expect(client.destroyed).toBe(false) diff --git a/src/utils/udsClient.ts b/src/utils/udsClient.ts index 45e868c33..1f1a6eee8 100644 --- a/src/utils/udsClient.ts +++ b/src/utils/udsClient.ts @@ -266,7 +266,10 @@ export async function sendToUdsSocket( /** * Connect to a peer and return the raw socket for bidirectional communication. - * The caller is responsible for managing the connection lifecycle. + * The caller is responsible for managing the connection lifecycle, including + * attaching an 'error' listener immediately after the Promise resolves. This + * function detaches its internal error listener on successful connect so + * caller-owned socket errors are not silently swallowed. */ export function connectToPeer( socketPath: string,