diff --git a/apps/desktop/src/main/load-health.test.ts b/apps/desktop/src/main/load-health.test.ts index e547daa4836..aac0ee58109 100644 --- a/apps/desktop/src/main/load-health.test.ts +++ b/apps/desktop/src/main/load-health.test.ts @@ -3,14 +3,20 @@ import { attachLoadHealth, classifyLoadError } from '@/main/load-health' import { BrowserWindow as MockBrowserWindow } from '@/test/electron-mock' describe('classifyLoadError', () => { + const SELF_HOSTED_URL = 'http://sim.corp.internal:3000/workspace' + it('does NOT ignore ERR_FAILED (-2) or ERR_IO_PENDING (-1)', () => { - expect(classifyLoadError(-2)).toBe('unreachable') - expect(classifyLoadError(-1)).toBe('unreachable') + expect(classifyLoadError(-2, SELF_HOSTED_URL)).toBe('unreachable') + expect(classifyLoadError(-1, SELF_HOSTED_URL)).toBe('unreachable') }) it('reports ERR_ADDRESS_UNREACHABLE as a local-network block only under Local Network privacy', () => { - expect(classifyLoadError(-109, true)).toBe('local_network') - expect(classifyLoadError(-109, false)).toBe('unreachable') + expect(classifyLoadError(-109, SELF_HOSTED_URL, true)).toBe('local_network') + expect(classifyLoadError(-109, SELF_HOSTED_URL, false)).toBe('unreachable') + }) + + it('never blames Local Network privacy for Sim Cloud, which is public', () => { + expect(classifyLoadError(-109, 'https://www.sim.ai/workspace', true)).toBe('unreachable') }) }) diff --git a/apps/desktop/src/main/load-health.ts b/apps/desktop/src/main/load-health.ts index 56c73d89f45..29019c2af2d 100644 --- a/apps/desktop/src/main/load-health.ts +++ b/apps/desktop/src/main/load-health.ts @@ -1,6 +1,7 @@ import { release } from 'node:os' import { createLogger } from '@sim/logger' import type { BrowserWindow } from 'electron' +import { isSimCloudOrigin } from '@/main/config' import { type EventRecorder, scrubUrl } from '@/main/observability' const logger = createLogger('DesktopLoadHealth') @@ -32,6 +33,7 @@ export type LoadErrorKind = */ export function classifyLoadError( errorCode: number, + url: string, localNetworkPrivacy: boolean = hasLocalNetworkPrivacy() ): LoadErrorKind { // Only ERR_ABORTED (-3) and success (0) are ignored. ERR_FAILED (-2) and @@ -54,7 +56,8 @@ export function classifyLoadError( // macOS Local Network privacy fails the socket with EHOSTUNREACH, which // Chromium reports as ERR_ADDRESS_UNREACHABLE (-109), so a self-hosted server // on a private address looks like a routing failure until Sim is allowed. - if (errorCode === -109 && localNetworkPrivacy) { + // Sim Cloud is public, so that permission can never be what blocked it. + if (errorCode === -109 && localNetworkPrivacy && !isSimCloudOrigin(url)) { return 'local_network' } return 'unreachable' @@ -151,7 +154,7 @@ export function attachLoadHealth(win: BrowserWindow, deps: LoadHealthDeps): Load return } clearTimeout(watchdogTimer) - const kind = classifyLoadError(errorCode) + const kind = classifyLoadError(errorCode, validatedURL) if (kind === 'ignored') { return }