openclaw/src/macos/gateway-daemon.test.ts
Richard A bef24dc4b0 fix(gateway): install unhandled rejection handler in macOS daemon (#3815)
The gateway daemon entrypoint did not call installUnhandledRejectionHandler(),
causing transient fetch/network errors to crash the process. The CLI and relay
paths already install it; this adds the same protection to the daemon path.

Closes #3815
2026-01-29 20:57:32 +04:00

60 lines
1.8 KiB
TypeScript

import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import process from "node:process";
describe("gateway-daemon unhandled rejection handler", () => {
let exitCalls: Array<string | number | null> = [];
let consoleErrorSpy: ReturnType<typeof vi.spyOn>;
let consoleWarnSpy: ReturnType<typeof vi.spyOn>;
beforeEach(async () => {
exitCalls = [];
vi.spyOn(process, "exit").mockImplementation((code: string | number | null | undefined) => {
if (code !== undefined && code !== null) {
exitCalls.push(code);
}
});
consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
// Install the handler (same import the daemon uses)
const { installUnhandledRejectionHandler } = await import(
"../infra/unhandled-rejections.js"
);
installUnhandledRejectionHandler();
});
afterEach(() => {
vi.restoreAllMocks();
});
it("does NOT exit on transient fetch failures (ECONNRESET)", () => {
const fetchErr = Object.assign(new TypeError("fetch failed"), {
cause: { code: "ECONNRESET" },
});
process.emit("unhandledRejection", fetchErr, Promise.resolve());
expect(exitCalls).toEqual([]);
expect(consoleWarnSpy).toHaveBeenCalledWith(
"[moltbot] Non-fatal unhandled rejection (continuing):",
expect.stringContaining("fetch failed"),
);
});
it("exits on fatal errors like OOM", () => {
const oomErr = Object.assign(new Error("Out of memory"), {
code: "ERR_OUT_OF_MEMORY",
});
process.emit("unhandledRejection", oomErr, Promise.resolve());
expect(exitCalls).toEqual([1]);
expect(consoleErrorSpy).toHaveBeenCalledWith(
"[moltbot] FATAL unhandled rejection:",
expect.stringContaining("Out of memory"),
);
});
});