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
This commit is contained in:
parent
cb4b3f74b5
commit
bef24dc4b0
@ -14,6 +14,7 @@ Status: beta.
|
|||||||
- Memory Search: allow extra paths for memory indexing. (#3600) Thanks @kira-ariaki.
|
- Memory Search: allow extra paths for memory indexing. (#3600) Thanks @kira-ariaki.
|
||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
|
- Gateway: prevent crash on transient fetch/network failures (#3815)
|
||||||
- Providers: add Venice AI integration; update Moonshot Kimi references to kimi-k2.5; update MiniMax API endpoint/format. (#2762, #3064)
|
- Providers: add Venice AI integration; update Moonshot Kimi references to kimi-k2.5; update MiniMax API endpoint/format. (#2762, #3064)
|
||||||
- Telegram: quote replies, edit-message action, silent sends, sticker support + vision caching, linkPreview toggle, plugin sendPayload support. (#2900, #2394, #2382, #2548, #1700, #1917)
|
- Telegram: quote replies, edit-message action, silent sends, sticker support + vision caching, linkPreview toggle, plugin sendPayload support. (#2900, #2394, #2382, #2548, #1700, #1917)
|
||||||
- Discord: configurable privileged gateway intents for presences/members. (#2266) Thanks @kentaro.
|
- Discord: configurable privileged gateway intents for presences/members. (#2266) Thanks @kentaro.
|
||||||
|
|||||||
59
src/macos/gateway-daemon.test.ts
Normal file
59
src/macos/gateway-daemon.test.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
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"),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -41,6 +41,10 @@ async function main() {
|
|||||||
(globalThis as unknown as { Long?: unknown }).Long = Long;
|
(globalThis as unknown as { Long?: unknown }).Long = Long;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prevent crashes on transient fetch/network failures (#3815)
|
||||||
|
const { installUnhandledRejectionHandler } = await import("../infra/unhandled-rejections.js");
|
||||||
|
installUnhandledRejectionHandler();
|
||||||
|
|
||||||
const [
|
const [
|
||||||
{ loadConfig },
|
{ loadConfig },
|
||||||
{ startGatewayServer },
|
{ startGatewayServer },
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user