

























@@ -181,6 +181,46 @@ describe("logs cli", () => {
181181expect(stderrWrites.join("")).toContain("reading local log file instead");
182182});
183183184+it("falls back to the configured Gateway file log on loopback gateway close errors", async () => {
185+callGatewayFromCli.mockRejectedValueOnce(
186+new Error("gateway closed (1000 normal closure): no close reason"),
187+);
188+readConfiguredLogTail.mockResolvedValueOnce({
189+file: "/tmp/openclaw.log",
190+cursor: 5,
191+size: 5,
192+lines: ["local fallback line"],
193+truncated: false,
194+reset: false,
195+});
196+197+const stdoutWrites = captureStdoutWrites();
198+const stderrWrites = captureStderrWrites();
199+200+await runLogsCli(["logs"]);
201+202+expect(readConfiguredLogTail).toHaveBeenCalledTimes(1);
203+expect(stdoutWrites.join("")).toContain("local fallback line");
204+expect(stderrWrites.join("")).toContain("Local Gateway RPC unavailable");
205+});
206+207+it("does not use local fallback for explicit Gateway URLs", async () => {
208+callGatewayFromCli.mockRejectedValueOnce(
209+new Error("gateway closed (1000 normal closure): no close reason"),
210+);
211+212+const stdoutWrites = captureStdoutWrites();
213+const stderrWrites = captureStderrWrites();
214+const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => undefined as never);
215+216+await runLogsCli(["logs", "--url", "ws://127.0.0.1:18789"]);
217+218+expect(readConfiguredLogTail).not.toHaveBeenCalled();
219+expect(stdoutWrites.join("")).not.toContain("local fallback line");
220+expect(stderrWrites.join("")).toContain("Gateway not reachable");
221+expect(exitSpy).toHaveBeenCalledWith(1);
222+});
223+184224describe("formatLogTimestamp", () => {
185225it("formats UTC timestamp in plain mode by default", () => {
186226const result = formatLogTimestamp("2025-01-01T12:00:00.000Z");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。