Commit 5fe3aeb2ce

5fe3aeb2cefc41b8b96d99d47d967eb7aa070c98

parent: 2ed92d773a

Unsigned

cmc <hello@cleberg.net> · 2026-07-24 23:34 UTC

fix: surface the real NWListener error and drop conflicting requiredLocalEndpoint (#30)

The Local API failed to start with a generic "Could not start Local API on
port 47821" and no actionable cause. Two problems:

1. The NWListener construction catch discarded the caught error and
   substituted a generic string, so the real NWError was never surfaced or
   logged. Now the underlying error is logged via stateLogger (matching the
   .failed branch) and appended to the thrown message.

2. parameters.requiredLocalEndpoint pinned 127.0.0.1:<port> while the same
   port was passed as the listener's on: argument. Pinning a required local
   endpoint conflicts with the listener's own port assignment; acceptLocalOnly
   already constrains binding to the local link. Dropped requiredLocalEndpoint,
   keeping acceptLocalOnly + allowLocalEndpointReuse.

Layout: unified · split

LocalAPIService.swift +4 −5
@@ -372,10 +372,6 @@ private final class LocalAPIServer: @unchecked Sendable {
372 let parameters = NWParameters.tcp 372 let parameters = NWParameters.tcp
373 parameters.acceptLocalOnly = true 373 parameters.acceptLocalOnly = true
374 parameters.allowLocalEndpointReuse = true 374 parameters.allowLocalEndpointReuse = true
375 parameters.requiredLocalEndpoint = .hostPort(
376 host: .ipv4(IPv4Address.loopback),
377 port: NWEndpoint.Port(rawValue: UInt16(port)) ?? .any
378 )
379 375
380 let listener: NWListener 376 let listener: NWListener
381 do { 377 do {
@@ -384,7 +380,10 @@ private final class LocalAPIServer: @unchecked Sendable {
384 on: NWEndpoint.Port(rawValue: UInt16(port)) ?? .any 380 on: NWEndpoint.Port(rawValue: UInt16(port)) ?? .any
385 ) 381 )
386 } catch { 382 } catch {
387 throw LocalAPIServerError.serverStartFailed("Could not start Local API on port \(port).") 383 stateLogger("Failed: \(error.localizedDescription)")
384 throw LocalAPIServerError.serverStartFailed(
385 "Could not start Local API on port \(port): \(error.localizedDescription)"
386 )
388 } 387 }
389 388
390 listener.newConnectionHandler = { [weak self] connection in 389 listener.newConnectionHandler = { [weak self] connection in