diff --git a/src/infra/system-presence.networkinterfaces-error.test.ts b/src/infra/system-presence.networkinterfaces-error.test.ts new file mode 100644 index 000000000..d31f5f5ad --- /dev/null +++ b/src/infra/system-presence.networkinterfaces-error.test.ts @@ -0,0 +1,33 @@ +import { describe, expect, it, vi } from "vitest"; + +const realOs = await vi.importActual("node:os"); + +vi.mock("node:os", () => { + const hostname = () => "moltbot-test-host"; + const platform = () => "linux"; + const networkInterfaces = () => { + throw new Error("uv_interface_addresses returned Unknown system error 1"); + }; + return { + ...realOs, + default: { + ...realOs, + hostname, + platform, + networkInterfaces, + }, + hostname, + platform, + networkInterfaces, + }; +}); + +describe("system-presence", () => { + it("does not crash when os.networkInterfaces throws", async () => { + vi.resetModules(); + const { listSystemPresence } = await import("./system-presence.js"); + const entries = listSystemPresence(); + expect(entries.length).toBeGreaterThan(0); + expect(entries.some((entry) => entry.host === "moltbot-test-host")).toBe(true); + }); +}); diff --git a/src/infra/system-presence.ts b/src/infra/system-presence.ts index 0e5d453ac..23c676ae1 100644 --- a/src/infra/system-presence.ts +++ b/src/infra/system-presence.ts @@ -39,21 +39,27 @@ function normalizePresenceKey(key: string | undefined): string | undefined { } function resolvePrimaryIPv4(): string | undefined { - const nets = os.networkInterfaces(); - const prefer = ["en0", "eth0"]; - const pick = (names: string[]) => { - for (const name of names) { - const list = nets[name]; - const entry = list?.find((n) => n.family === "IPv4" && !n.internal); - if (entry?.address) return entry.address; - } - for (const list of Object.values(nets)) { - const entry = list?.find((n) => n.family === "IPv4" && !n.internal); - if (entry?.address) return entry.address; - } - return undefined; - }; - return pick(prefer) ?? os.hostname(); + try { + const nets = os.networkInterfaces(); + const prefer = ["en0", "eth0"]; + const pick = (names: string[]) => { + for (const name of names) { + const list = nets[name]; + const entry = list?.find((n) => n.family === "IPv4" && !n.internal); + if (entry?.address) return entry.address; + } + for (const list of Object.values(nets)) { + const entry = list?.find((n) => n.family === "IPv4" && !n.internal); + if (entry?.address) return entry.address; + } + return undefined; + }; + return pick(prefer) ?? os.hostname(); + } catch { + // Some environments (e.g. certain VPS setups) can throw from os.networkInterfaces(). + // Fall back to hostname so the CLI can still boot. + return os.hostname(); + } } function initSelfPresence() {