From 2c2fa3d25c0e6327dbbf95f35344b6f618ff2f84 Mon Sep 17 00:00:00 2001 From: Jinwoo-H Date: Mon, 7 Sep 2026 15:37:13 -0400 Subject: [PATCH] fix(relay): classify an empty region catalog as catalog-incomplete, not all-unreachable --- src/main/runtime/relay/relay-region-probe-log.test.ts | 10 ++++++++++ src/main/runtime/relay/relay-region-probe-log.ts | 7 ++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/runtime/relay/relay-region-probe-log.test.ts b/src/main/runtime/relay/relay-region-probe-log.test.ts index 4c1de3ac475..2bdd1881bc5 100644 --- a/src/main/runtime/relay/relay-region-probe-log.test.ts +++ b/src/main/runtime/relay/relay-region-probe-log.test.ts @@ -185,6 +185,16 @@ describe('Relay region probe log', () => { expect(probeEvents(events)[0]!.reason).toBe('all-unreachable') }) + it('reports an empty catalog as catalog-incomplete, since nothing was probed', async () => { + const { resolver, events } = resolverWithLog({ + path: userDataPath(), + fetch: catalogFetch([]), + probe: sampledProbe({}) + }) + await expect(resolver.resolve()).resolves.toBeUndefined() + expect(probeEvents(events)[0]).toMatchObject({ reason: 'catalog-incomplete', regions: [] }) + }) + it('reports a lone flapping region as all-rejected, and a lone healthy one as catalog-incomplete', async () => { const path = userDataPath() const flapping = resolverWithLog({ diff --git a/src/main/runtime/relay/relay-region-probe-log.ts b/src/main/runtime/relay/relay-region-probe-log.ts index 9e7295ab38d..cdb924ea108 100644 --- a/src/main/runtime/relay/relay-region-probe-log.ts +++ b/src/main/runtime/relay/relay-region-probe-log.ts @@ -131,7 +131,12 @@ function refreshReason( return best && selected.region !== best.region ? 'held-previous' : 'measured' } // Reachability first: a support census counting all-unreachable to spot - // client-side network breakage must not lose those runs to a roll wave. + // client-side network breakage must not lose those runs to a roll wave. An + // empty catalog (every region drained at once) probed nothing, so it is the + // catalog that is incomplete, not the network. + if (reports.length === 0) { + return 'catalog-incomplete' + } if (reports.every((report) => report.verdict === 'unreachable')) { return 'all-unreachable' }