]> Piment Noir Git Repositories - e-mobility-charging-stations-simulator.git/commitdiff
fix(cli): validate connect timeout budget — reject NaN/0/negative before race
authorJérôme Benoit <jerome.benoit@sap.com>
Wed, 15 Apr 2026 20:15:42 +0000 (22:15 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Wed, 15 Apr 2026 20:16:02 +0000 (22:16 +0200)
ui/cli/src/client/lifecycle.ts
ui/cli/tests/lifecycle.test.ts

index bf1f69e75938877ceae65753305659e77d8c9123..00fc109352408f89f164ea45ebff93f91e01477c 100644 (file)
@@ -46,6 +46,9 @@ export const executeCommand = async (options: ExecuteOptions): Promise<void> =>
   activeClient = client
 
   const budget = timeoutMs ?? UI_WEBSOCKET_REQUEST_TIMEOUT_MS
+  if (!Number.isFinite(budget) || budget <= 0) {
+    throw new Error(`Invalid timeout: ${String(budget)}ms (must be > 0)`)
+  }
   const startTime = Date.now()
 
   let connectTimeoutId: ReturnType<typeof setTimeout> | undefined
index a8ca7aa417feb8cb052b42436f7de4f96dccb8d7..d5f4a4ad83181fc4a3b4bd1e809167bc8d7c3dc8 100644 (file)
@@ -34,4 +34,21 @@ await describe('lifecycle', async () => {
   await it('should export executeCommand function', () => {
     assert.strictEqual(typeof executeCommand, 'function')
   })
+
+  await it('should reject executeCommand with NaN timeout', async () => {
+    await assert.rejects(
+      executeCommand({
+        config: { host: 'localhost', port: 8080, protocol: 'ui', version: '0.0.1' },
+        formatter: { error: () => undefined, output: () => undefined },
+        payload: {},
+        procedureName: 'listChargingStations' as never,
+        timeoutMs: Number.NaN,
+      }),
+      (error: Error) => {
+        assert.ok(error.message.includes('Invalid timeout'))
+        assert.ok(error.message.includes('NaN'))
+        return true
+      }
+    )
+  })
 })