Files
electric-cherry/src/lib/ui/komodoError.ts
T
joshandClaude Opus 4.7 1d05f5df1b Structured Komodo port diagnostics + probe button
komodoResolveGamePort silently returned null for six distinct failure
modes (unconfigured, no-name, unreachable, http-error, unparseable,
no-udp-in-response), which made "no game_port — Komodo did not return
one" indistinguishable from an auth failure or an unrecognized response
shape. Adds komodoResolvePortDetailed returning a discriminated union
with the failure reason, HTTP status, and a truncated response snippet.

extractUdpPort broadens to cover four more shapes seen in the wild:
extra host-port field names (HostPort/hostPort/host_port/PublicPort),
`type` as a protocol alias, host-network strings ("28962/udp"), and the
docker-inspect container-keyed form ({ "28960/udp": [{ HostPort }] }).
Arrays reached via a ports-flavored key now win over accidental matches
elsewhere in the tree.

New POST /api/servers/[name]/probe-komodo triggers a fresh lookup,
caches the port on success, and returns the structured result. The RCON
diagnostic panel gains a Probe Komodo button (shown when endpoint is
unresolved and Komodo is configured) that renders the snippet inline —
so unrecognized shapes surface directly instead of vanishing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-09-12 09:21:36 -04:00

28 lines
1.4 KiB
TypeScript

export type KomodoPortFailure =
| 'unconfigured'
| 'no-name'
| 'unreachable'
| 'http-error'
| 'unparseable'
| 'no-udp-in-response';
/** Short fix hint per failure reason, shown under the Komodo probe result. */
export function komodoFixHint(reason: KomodoPortFailure, httpStatus?: number): string {
switch (reason) {
case 'unconfigured':
return 'Set KOMODO_ADDRESS, KOMODO_API_KEY, and KOMODO_API_SECRET in the container env.';
case 'no-name':
return 'This server row has no komodo_name — set it via SQL or via the fleet config.';
case 'unreachable':
return 'Network, DNS, or timeout. Check that KOMODO_ADDRESS is reachable from this container.';
case 'http-error':
if (httpStatus === 401 || httpStatus === 403) return 'Auth rejected — verify KOMODO_API_KEY and KOMODO_API_SECRET.';
if (httpStatus === 404) return 'Endpoint or deployment not found — check komodo_name matches the Komodo UI exactly.';
return `Komodo returned ${httpStatus ?? 'an error'}. Check the endpoint path and credentials.`;
case 'unparseable':
return 'Response was not JSON — is KOMODO_ADDRESS pointing at the Core API (not the Periphery)?';
case 'no-udp-in-response':
return 'Parsed the response but no UDP port matched our known shapes. See the snippet below and extend extractUdpPort.';
}
}