Unwrap fetch errors + show URL in Komodo probe result

The probe surfaced "unreachable: This operation was aborted" — technically
correct (an AbortController fired the fetch timeout) but useless for
diagnosing whether it's a wrong URL, blocked route, or firewall. Node's
fetch also hides real network causes (ECONNREFUSED, ENOTFOUND,
EHOSTUNREACH) under `.cause`, and the default message just says
"fetch failed".

describeFetchError() now unwraps AbortError to "timed out after 10000ms
dialing <url>" and pulls `.cause.code/.cause.message` for network
failures. KomodoPortResult gains a `url` field, always populated, so the
probe panel can surface the exact URL we dialed in a code block —
operators can then `curl` it from the container to confirm reachability.

komodoRestart benefits from the same unwrapping since it uses the same
komodoCall() transport.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-09-12 09:28:15 -04:00
co-authored by Claude Opus 4.7
parent 1d05f5df1b
commit 08de5a4064
2 changed files with 68 additions and 6 deletions
+31
View File
@@ -16,6 +16,7 @@
detail?: string;
httpStatus?: number;
snippet?: string;
url?: string;
}
interface Server {
@@ -212,6 +213,12 @@
{#if komodoProbe.httpStatus} · HTTP {komodoProbe.httpStatus}{/if}
</span>
</div>
{#if komodoProbe.url}
<div class="probe-url">
<span class="k">tried</span>
<code>{komodoProbe.url}</code>
</div>
{/if}
{#if komodoProbe.reason}
<div class="hint">{komodoFixHint(komodoProbe.reason, komodoProbe.httpStatus)}</div>
{/if}
@@ -505,6 +512,30 @@
}
.probe-detail strong { color: var(--spark-500); }
.probe-url {
display: flex;
align-items: baseline;
gap: 8px;
margin-top: 8px;
padding: 6px 12px;
background: var(--cherry-875);
border-radius: var(--r-sm);
border: 1px solid var(--cherry-700);
font-size: 11px;
}
.probe-url .k {
color: var(--ink-500);
font-family: var(--font-body);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 1px;
}
.probe-url code {
color: var(--cream);
font-family: var(--font-mono);
word-break: break-all;
}
.snippet-details {
margin-top: 10px;
font-family: var(--font-mono);