fix: skip failure bundles for gateway lock exits

This commit is contained in:
Gustavo Madeira Santana
2026-04-22 19:25:01 -04:00
parent e9b1cc056e
commit 87653f0938
2 changed files with 25 additions and 1 deletions

View File

@@ -34,6 +34,11 @@ const recoverConfigFromJsonRootSuffix = vi.fn<(snapshot?: unknown) => Promise<bo
const writeRestartSentinel = vi.fn<(payload?: unknown) => Promise<string>>(
async (_payload?: unknown) => "/tmp/restart-sentinel.json",
);
const writeDiagnosticStabilityBundleForFailureSync = vi.fn((_reason: string, _error: unknown) => ({
status: "written" as const,
message: "wrote stability bundle: /tmp/openclaw-stability.json",
path: "/tmp/openclaw-stability.json",
}));
const controlUiState = vi.hoisted(() => ({
root: "/tmp/openclaw-control-ui" as string | null,
}));
@@ -110,6 +115,11 @@ vi.mock("../../logging/console.js", () => ({
setConsoleTimestampPrefix: () => undefined,
}));
vi.mock("../../logging/diagnostic-stability-bundle.js", () => ({
writeDiagnosticStabilityBundleForFailureSync: (reason: string, error: unknown) =>
writeDiagnosticStabilityBundleForFailureSync(reason, error),
}));
vi.mock("../../logging/subsystem.js", () => ({
createSubsystemLogger: () => ({
info: (message: string) => {
@@ -167,6 +177,7 @@ describe("gateway run option collisions", () => {
recoverConfigFromJsonRootSuffix.mockResolvedValue(false);
writeRestartSentinel.mockReset();
writeRestartSentinel.mockResolvedValue("/tmp/restart-sentinel.json");
writeDiagnosticStabilityBundleForFailureSync.mockClear();
startGatewayServer.mockClear();
setGatewayWsLogStyle.mockClear();
setVerbose.mockClear();
@@ -253,6 +264,19 @@ describe("gateway run option collisions", () => {
);
});
it("does not write startup failure bundles for expected gateway lock conflicts", async () => {
const err = Object.assign(new Error("gateway already running on port 18789"), {
name: "GatewayLockError",
});
startGatewayServer.mockRejectedValueOnce(err);
await expect(runGatewayCli(["gateway", "run", "--allow-unconfigured"])).rejects.toThrow(
"__exit__:0",
);
expect(writeDiagnosticStabilityBundleForFailureSync).not.toHaveBeenCalled();
});
it("blocks startup when the observed snapshot loses gateway.mode even if loadConfig still says local", async () => {
configState.cfg = {
gateway: {

View File

@@ -686,7 +686,6 @@ async function runGatewayCommand(opts: GatewayRunOpts) {
}
}
} catch (err) {
maybeWriteGatewayStartupFailureBundle(err);
if (isGatewayLockError(err)) {
const errMessage = formatErrorMessage(err);
defaultRuntime.error(
@@ -706,6 +705,7 @@ async function runGatewayCommand(opts: GatewayRunOpts) {
defaultRuntime.exit(isHealthyGatewayLockError(err) ? 0 : 1);
return;
}
maybeWriteGatewayStartupFailureBundle(err);
defaultRuntime.error(`Gateway failed to start: ${String(err)}`);
defaultRuntime.exit(1);
}