Skip to content

Commit 5f13233

Browse files
committed
debug(mobile): surface iOS discovery diagnostic on-screen (Alert)
Show the discovery self-test result in an on-screen Alert so no console is needed to see where iOS breaks: Flux API (HTTPS) status → gateway /v1/info (cleartext) status → body read (arrayBuffer vs text). Pops once per launch.
1 parent 702ae5b commit 5f13233

1 file changed

Lines changed: 41 additions & 29 deletions

File tree

clients/mobile/src/lib/gateways.ts

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* count, a representative city and a latency reading for the dot colour. This
77
* module does that shaping and nothing else — all networking lives in core.
88
*/
9+
import { Alert } from 'react-native';
910
import { discoverGateways, pingGateway } from '@cumulusvpn/core';
1011
import type { GatewayInfo } from '@cumulusvpn/core';
1112
import { bundledSpecs, seedNodeIps } from './directory';
@@ -293,45 +294,56 @@ const diagFetch: typeof fetch = async (input, init) => {
293294
};
294295

295296
/**
296-
* TEMP: independently fetch one gateway's /v1/info and log status + how the body
297-
* reads (arrayBuffer vs text) — `fetchSigned` uses res.arrayBuffer(), which is a
298-
* known-fragile path on RN iOS. Runs off the first Flux-API candidate so it never
299-
* touches the real discovery reads. Non-blocking; failures only log.
297+
* TEMP: step-by-step discovery self-test that surfaces the result **on screen**
298+
* (Alert) so no console is needed. Walks the exact path discovery uses — Flux API
299+
* (HTTPS) → gateway /v1/info (cleartext) → body read via arrayBuffer (what
300+
* fetchSigned uses, fragile on RN iOS) vs text — and reports where it breaks.
301+
* Runs once per launch, independent of the real discovery reads.
300302
*/
303+
let diagShown = false;
301304
async function diagArrayBufferSelfTest(): Promise<void> {
305+
if (diagShown) return;
306+
diagShown = true;
307+
const steps: string[] = [];
302308
try {
303309
const specs = bundledSpecs();
304-
if (specs.length === 0) return;
305-
const locRes = await fetch(`https://api.runonflux.io/apps/location/${specs[0]}`);
306-
const loc = (await locRes.json()) as { data?: { ip?: string }[] };
307-
const ip = loc.data?.[0]?.ip?.split(':')[0];
308-
if (!ip) {
309-
// eslint-disable-next-line no-console
310-
console.warn('[CVPN-DISCOVERY] selftest: no candidate IP from Flux API');
311-
return;
312-
}
313-
const url = `http://${ip}:51821/v1/info`;
314-
const res = await fetch(url);
315-
let ab = 'n/a';
316-
let txt = 'n/a';
310+
steps.push(`specs=${specs.length}`);
311+
const apiUrl = `https://api.runonflux.io/apps/location/${specs[0]}`;
312+
let ip: string | undefined;
317313
try {
318-
ab = String((await res.clone().arrayBuffer()).byteLength);
314+
const locRes = await fetch(apiUrl);
315+
const loc = (await locRes.json()) as { data?: { ip?: string }[] };
316+
ip = loc.data?.[0]?.ip?.split(':')[0];
317+
steps.push(`fluxAPI=${locRes.status} ip=${ip ?? 'none'}`);
319318
} catch (e) {
320-
ab = `ERR ${String((e as Error)?.message ?? e)}`;
319+
steps.push(`fluxAPI=FETCH_ERR ${String((e as Error)?.message ?? e)}`);
321320
}
322-
try {
323-
txt = String((await res.text()).length);
324-
} catch (e) {
325-
txt = `ERR ${String((e as Error)?.message ?? e)}`;
321+
if (ip) {
322+
const url = `http://${ip}:51821/v1/info`;
323+
try {
324+
const res = await fetch(url);
325+
steps.push(`gateway=${res.status}`);
326+
try {
327+
steps.push(`arrayBuffer=${(await res.clone().arrayBuffer()).byteLength}B`);
328+
} catch (e) {
329+
steps.push(`arrayBuffer=ERR ${String((e as Error)?.message ?? e)}`);
330+
}
331+
try {
332+
steps.push(`text=${(await res.text()).length}chars`);
333+
} catch (e) {
334+
steps.push(`text=ERR ${String((e as Error)?.message ?? e)}`);
335+
}
336+
} catch (e) {
337+
steps.push(`gateway=FETCH_ERR ${String((e as Error)?.message ?? e)}`);
338+
}
326339
}
327-
// eslint-disable-next-line no-console
328-
console.warn(
329-
`[CVPN-DISCOVERY] selftest ${url} status=${res.status} arrayBuffer=${ab} text=${txt}`,
330-
);
331340
} catch (e) {
332-
// eslint-disable-next-line no-console
333-
console.warn(`[CVPN-DISCOVERY] selftest FAILED :: ${String((e as Error)?.message ?? e)}`);
341+
steps.push(`selftest threw ${String((e as Error)?.message ?? e)}`);
334342
}
343+
const report = steps.join('\n');
344+
// eslint-disable-next-line no-console
345+
console.warn(`[CVPN-DISCOVERY]\n${report}`);
346+
Alert.alert('Discovery diagnostic', report);
335347
}
336348

337349
/**

0 commit comments

Comments
 (0)