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>
28 lines
1.4 KiB
TypeScript
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.';
|
|
}
|
|
}
|