fix(egress): retry a gateway CONNECT once on connection failure and log each failed attempt

Merged
WA
6d ago
+99-8

Summary

  • openGatewayTunnel retries the CONNECT once when it fails before a tunnel exists at the connection level (socket reset, TLS, connect timeout) or the proxy answers 5xx; no upstream bytes are sent before a 200, so the retry is safe
  • Each attempt opens a fresh undici Client, so the load balancer can pick another gateway task; each attempt keeps the existing CONNECT_TIMEOUT_MS (no new timeouts)
  • 4xx answers (407 credential, 403 admission) and UNSUPPORTED_TRANSPORT never retry
  • One logger.warn per failed attempt with gateway id, organization id, attempt, proxy status code, and error name/code; no token, CA, or gateway URL is logged
  • The thrown error stays GATEWAY_UNAVAILABLE, so callers and user-facing messages are unchanged
  • Both the pinned and DNS-guarded fetch paths reach the tunnel through createGatewayDispatcher, so one retry covers both; nothing above it retries OutboundRoutingError, and undici's connector exposes no request signal to plumb

Type of Change

  • Bug fix

Testing

  • gateway.server.test.ts (real TLS CONNECT proxy) gains three cases: a dropped first CONNECT recovers on the second and the request succeeds; a 407 fails after exactly one attempt; a reset then a 503 fails after exactly two attempts
  • Red check: the first and third fail on the pre-change code; the 407 case fails when the retry is made unconditional
  • vitest run lib/core/network/ (60 passed), biome, check:explicit-any, check:comment-hygiene, check:utils; CI runs the rest

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing (new tests pass the test-audit authoring gate)
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)