fix(bonjour): suppress ciao crash when networkInterfaces() is denied · openclaw/openclaw@fb5b46a
iot2edge
·
2026-04-28
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -359,6 +359,13 @@ export async function startGatewayBonjourAdvertiser(
|
359 | 359 | |
360 | 360 | if (classification.kind === "cancellation") { |
361 | 361 | logger.debug(`bonjour: ignoring unhandled ciao rejection: ${classification.formatted}`); |
| 362 | +} else if (classification.kind === "interface-enumeration-failure") { |
| 363 | +// Restricted sandboxes can refuse os.networkInterfaces(); mDNS cannot |
| 364 | +// function without it, so surface a single warning and skip recovery. |
| 365 | +// Recovery would just re-enter the same failing syscall. |
| 366 | +logger.warn( |
| 367 | +`bonjour: disabling mDNS — networkInterfaces() unavailable in this environment: ${classification.formatted}`, |
| 368 | +); |
362 | 369 | } else { |
363 | 370 | const label = |
364 | 371 | classification.kind === "netmask-assertion" ? "netmask assertion" : "interface assertion"; |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -100,6 +100,27 @@ describe("bonjour-ciao", () => {
|
100 | 100 | expect(ignoreCiaoUnhandledRejection(error)).toBe(true); |
101 | 101 | }); |
102 | 102 | |
| 103 | +it("classifies networkInterfaces SystemError failures (restricted sandboxes)", () => { |
| 104 | +const err = Object.assign( |
| 105 | +new Error("A system error occurred: uv_interface_addresses returned Unknown system error 1"), |
| 106 | +{ name: "SystemError" }, |
| 107 | +); |
| 108 | +expect(classifyCiaoUnhandledRejection(err)).toEqual({ |
| 109 | +kind: "interface-enumeration-failure", |
| 110 | +formatted: |
| 111 | +"SystemError: A system error occurred: uv_interface_addresses returned Unknown system error 1", |
| 112 | +}); |
| 113 | +}); |
| 114 | + |
| 115 | +it("suppresses networkInterfaces failures wrapped in cause chains", () => { |
| 116 | +const inner = Object.assign( |
| 117 | +new Error("A system error occurred: uv_interface_addresses returned Unknown system error 1"), |
| 118 | +{ name: "SystemError" }, |
| 119 | +); |
| 120 | +const wrapper = new Error("ciao NetworkManager init failed", { cause: inner }); |
| 121 | +expect(ignoreCiaoUnhandledRejection(wrapper)).toBe(true); |
| 122 | +}); |
| 123 | + |
103 | 124 | it("keeps unrelated rejections visible", () => { |
104 | 125 | expect(ignoreCiaoUnhandledRejection(new Error("boom"))).toBe(false); |
105 | 126 | }); |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -5,11 +5,16 @@ const CIAO_INTERFACE_ASSERTION_MESSAGE_RE =
|
5 | 5 | /REACHED ILLEGAL STATE!?\s+IPV4 ADDRESS CHANGE FROM (?:DEFINED TO UNDEFINED|UNDEFINED TO DEFINED)!?/u; |
6 | 6 | const CIAO_NETMASK_ASSERTION_MESSAGE_RE = |
7 | 7 | /IP ADDRESS VERSION MUST MATCH\.\s+NETMASK CANNOT HAVE A VERSION DIFFERENT FROM THE ADDRESS!?/u; |
| 8 | +// Restricted sandboxes (NemoClaw, Docker-in-Docker, k3s with locked-down policy) |
| 9 | +// can refuse os.networkInterfaces(), which ciao calls during NetworkManager init. |
| 10 | +// Node surfaces this as a SystemError mentioning the libuv syscall by name. |
| 11 | +const CIAO_INTERFACE_ENUMERATION_FAILURE_RE = /\bUV_INTERFACE_ADDRESSES\b/u; |
8 | 12 | |
9 | 13 | export type CiaoProcessErrorClassification = |
10 | 14 | | { kind: "cancellation"; formatted: string } |
11 | 15 | | { kind: "interface-assertion"; formatted: string } |
12 | | -| { kind: "netmask-assertion"; formatted: string }; |
| 16 | +| { kind: "netmask-assertion"; formatted: string } |
| 17 | +| { kind: "interface-enumeration-failure"; formatted: string }; |
13 | 18 | |
14 | 19 | function collectCiaoProcessErrorCandidates(reason: unknown): unknown[] { |
15 | 20 | const queue: unknown[] = [reason]; |
@@ -64,6 +69,9 @@ export function classifyCiaoProcessError(reason: unknown): CiaoProcessErrorClass
|
64 | 69 | if (CIAO_NETMASK_ASSERTION_MESSAGE_RE.test(message)) { |
65 | 70 | return { kind: "netmask-assertion", formatted }; |
66 | 71 | } |
| 72 | +if (CIAO_INTERFACE_ENUMERATION_FAILURE_RE.test(message)) { |
| 73 | +return { kind: "interface-enumeration-failure", formatted }; |
| 74 | +} |
67 | 75 | } |
68 | 76 | return null; |
69 | 77 | } |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。