fix(daemon): prefer stderr over stale stdout in gateway restart diagnostics

Refs #93001.
This commit is contained in:
Alix-007
2026-06-16 00:09:41 +08:00
committed by GitHub
parent 95772c8541
commit f6a3ac7e58
2 changed files with 21 additions and 1 deletions
+17
View File
@@ -36,4 +36,21 @@ describe("readLastGatewayErrorLine", () => {
"gateway stdout current",
);
});
it("prefers the current stderr error over a stale stdout match on linux", async () => {
const stateDir = makeTempStateDir();
const homeDir = makeTempStateDir();
const env = { HOME: homeDir, OPENCLAW_STATE_DIR: stateDir };
const stateLogs = resolveGatewayLogPaths(env);
fs.mkdirSync(stateLogs.logDir, { recursive: true });
// stderr carries the real, current failure; stdout carries an older matching
// line. On non-darwin platforms stderr is the strongest failure signal, so
// it must win instead of the stale stdout match.
fs.writeFileSync(stateLogs.stderrPath, "failed to bind gateway socket EADDRINUSE\n", "utf8");
fs.writeFileSync(stateLogs.stdoutPath, "gateway start blocked: stale prior reason\n", "utf8");
await expect(readLastGatewayErrorLine(env, { platform: "linux" })).resolves.toBe(
"failed to bind gateway socket EADDRINUSE",
);
});
});
+4 -1
View File
@@ -40,7 +40,10 @@ export async function readLastGatewayErrorLine(
: resolveGatewayLogPaths(env);
const stderrRaw = readStderr ? await fs.readFile(stderrPath, "utf8").catch(() => "") : "";
const stdoutRaw = await fs.readFile(stdoutPath, "utf8").catch(() => "");
const lines = [...stderrRaw.split(/\r?\n/), ...stdoutRaw.split(/\r?\n/)].map((line) =>
// stderr is the strongest failure signal on non-darwin platforms, so place it
// last and scan from the end: the most recent stderr error line then wins over
// any (possibly stale) stdout match, matching the stderr-first fallback below.
const lines = [...stdoutRaw.split(/\r?\n/), ...stderrRaw.split(/\r?\n/)].map((line) =>
line.trim(),
);
for (let i = lines.length - 1; i >= 0; i -= 1) {