Skip to content

Commit f266b9e

Browse files
committed
fix: separate advertised endpoints error state and handle malformed custom URLs gracefully
Bug 1: getAdvertisedEndpoints() error was writing to desktopServerExposureError, sharing state with getServerExposureState(). Added a dedicated desktopAdvertisedEndpointsError state so endpoint fetch failures don't overwrite/corrupt the Network access error indicator. Bug 2: A single malformed URL in T3CODE_DESKTOP_HTTPS_ENDPOINTS caused the entire resolveDesktopCoreAdvertisedEndpoints to throw, discarding valid loopback and LAN endpoints. Wrapped the custom URL loop body in try-catch so bad entries are skipped with a warning.
1 parent 660f950 commit f266b9e

2 files changed

Lines changed: 28 additions & 12 deletions

File tree

apps/desktop/src/serverExposure.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -156,17 +156,21 @@ export function resolveDesktopCoreAdvertisedEndpoints(
156156
}
157157

158158
for (const customEndpointUrl of input.customHttpsEndpointUrls ?? []) {
159-
endpoints.push(
160-
createManualEndpoint({
161-
id: `manual:${customEndpointUrl}`,
162-
label: "Custom HTTPS",
163-
httpBaseUrl: customEndpointUrl,
164-
reachability: "public",
165-
hostedHttpsCompatibility: "compatible",
166-
status: "unknown",
167-
description: "User-configured HTTPS endpoint for this desktop backend.",
168-
}),
169-
);
159+
try {
160+
endpoints.push(
161+
createManualEndpoint({
162+
id: `manual:${customEndpointUrl}`,
163+
label: "Custom HTTPS",
164+
httpBaseUrl: customEndpointUrl,
165+
reachability: "public",
166+
hostedHttpsCompatibility: "compatible",
167+
status: "unknown",
168+
description: "User-configured HTTPS endpoint for this desktop backend.",
169+
}),
170+
);
171+
} catch {
172+
console.warn(`Skipping malformed custom endpoint URL: ${customEndpointUrl}`);
173+
}
170174
}
171175

172176
return endpoints;

apps/web/src/components/settings/ConnectionsSettings.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,9 @@ export function ConnectionsSettings() {
878878
ReadonlyArray<AdvertisedEndpoint>
879879
>([]);
880880
const [desktopServerExposureError, setDesktopServerExposureError] = useState<string | null>(null);
881+
const [desktopAdvertisedEndpointsError, setDesktopAdvertisedEndpointsError] = useState<
882+
string | null
883+
>(null);
881884
const [desktopPairingLinks, setDesktopPairingLinks] = useState<
882885
ReadonlyArray<ServerPairingLinkRecord>
883886
>([]);
@@ -1218,12 +1221,13 @@ export function ConnectionsSettings() {
12181221
if (cancelled) return;
12191222
const message =
12201223
error instanceof Error ? error.message : "Failed to load reachable endpoints.";
1221-
setDesktopServerExposureError(message);
1224+
setDesktopAdvertisedEndpointsError(message);
12221225
});
12231226
} else {
12241227
setDesktopServerExposureState(null);
12251228
setDesktopAdvertisedEndpoints([]);
12261229
setDesktopServerExposureError(null);
1230+
setDesktopAdvertisedEndpointsError(null);
12271231
}
12281232

12291233
return () => {
@@ -1241,6 +1245,7 @@ export function ConnectionsSettings() {
12411245
setDesktopServerExposureState(null);
12421246
setDesktopAdvertisedEndpoints([]);
12431247
setDesktopServerExposureError(null);
1248+
setDesktopAdvertisedEndpointsError(null);
12441249
}, [canManageLocalBackend]);
12451250
const visibleDesktopPairingLinks = useMemo(
12461251
() => desktopPairingLinks.filter((pairingLink) => pairingLink.role === "client"),
@@ -1337,6 +1342,13 @@ export function ConnectionsSettings() {
13371342
</AlertDialog>
13381343
}
13391344
/>
1345+
{desktopAdvertisedEndpointsError ? (
1346+
<div className="px-4 py-2">
1347+
<span className="block text-xs text-destructive">
1348+
{desktopAdvertisedEndpointsError}
1349+
</span>
1350+
</div>
1351+
) : null}
13401352
{desktopAdvertisedEndpoints.map((endpoint) => (
13411353
<AdvertisedEndpointListRow key={endpoint.id} endpoint={endpoint} />
13421354
))}

0 commit comments

Comments
 (0)