fix(googlechat): clear status after startup failures

This commit is contained in:
Vincent Koc
2026-06-17 17:30:26 +02:00
parent 1579d833d6
commit cf79735a65
2 changed files with 53 additions and 22 deletions

View File

@@ -44,6 +44,17 @@ export async function startGoogleChatGatewayAccount(ctx: {
audienceType: account.config.audienceType,
audience: account.config.audience,
});
let stopped = false;
const markStopped = () => {
if (stopped) {
return;
}
stopped = true;
statusSink({
running: false,
lastStopAt: Date.now(),
});
};
if (
isGoogleChatNativeApprovalClientEnabled({
cfg: ctx.cfg,
@@ -59,26 +70,28 @@ export async function startGoogleChatGatewayAccount(ctx: {
abortSignal: ctx.abortSignal,
});
}
await runPassiveAccountLifecycle({
abortSignal: ctx.abortSignal,
start: async () =>
await startGoogleChatMonitor({
account,
config: ctx.cfg,
runtime: ctx.runtime,
abortSignal: ctx.abortSignal,
webhookPath: account.config.webhookPath,
webhookUrl: account.config.webhookUrl,
statusSink,
}),
stop: async (unregister) => {
unregister?.();
},
onStop: async () => {
statusSink({
running: false,
lastStopAt: Date.now(),
});
},
});
try {
await runPassiveAccountLifecycle({
abortSignal: ctx.abortSignal,
start: async () =>
await startGoogleChatMonitor({
account,
config: ctx.cfg,
runtime: ctx.runtime,
abortSignal: ctx.abortSignal,
webhookPath: account.config.webhookPath,
webhookUrl: account.config.webhookUrl,
statusSink,
}),
stop: async (unregister) => {
unregister?.();
},
onStop: async () => {
markStopped();
},
});
} catch (error) {
markStopped();
throw error;
}
}

View File

@@ -1,5 +1,6 @@
// Googlechat tests cover setup plugin behavior.
import {
createStartAccountContext,
expectLifecyclePatch,
expectPendingUntilAbort,
startAccountAndTrackLifecycle,
@@ -12,6 +13,7 @@ import {
} from "openclaw/plugin-sdk/plugin-test-runtime";
import type { WizardPrompter } from "openclaw/plugin-sdk/plugin-test-runtime";
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/setup";
import type { ChannelAccountSnapshot } from "openclaw/plugin-sdk/status-helpers";
import { afterAll, afterEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../runtime-api.js";
import {
@@ -383,6 +385,22 @@ describe("googlechat setup", () => {
expectLifecyclePatch(patches, { running: true });
expectLifecyclePatch(patches, { running: false });
});
it("clears running status when monitor startup fails", async () => {
hoisted.startGoogleChatMonitor.mockRejectedValue(new Error("webhook bind failed"));
const patches: ChannelAccountSnapshot[] = [];
const task = startGoogleChatGatewayAccount(
createStartAccountContext({
account: buildAccount(),
statusPatchSink: (next) => patches.push({ ...next }),
}),
);
await expect(task).rejects.toThrow("webhook bind failed");
expectLifecyclePatch(patches, { running: true });
expectLifecyclePatch(patches, { running: false });
});
});
describe("resolveGoogleChatAccount", () => {