refactor: unify monitor abort lifecycle handling

This commit is contained in:
Peter Steinberger
2026-02-26 04:36:00 +01:00
parent 02c731826a
commit e915b4c64a
13 changed files with 319 additions and 103 deletions

View File

@@ -1,4 +1,4 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { monitorTelegramProvider } from "./monitor.js";
type MockCtx = {
@@ -160,19 +160,30 @@ vi.mock("../auto-reply/reply.js", () => ({
}));
describe("monitorTelegramProvider (grammY)", () => {
let consoleErrorSpy: { mockRestore: () => void } | undefined;
beforeEach(() => {
loadConfig.mockReturnValue({
agents: { defaults: { maxConcurrent: 2 } },
channels: { telegram: {} },
});
initSpy.mockClear();
runSpy.mockClear();
runSpy.mockReset().mockImplementation(() =>
makeRunnerStub({
task: () => Promise.reject(new Error("runSpy called without explicit test stub")),
}),
);
computeBackoff.mockClear();
sleepWithAbort.mockClear();
startTelegramWebhookSpy.mockClear();
registerUnhandledRejectionHandlerMock.mockClear();
resetUnhandledRejection();
createTelegramBotErrors.length = 0;
consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
});
afterEach(() => {
consoleErrorSpy?.mockRestore();
});
it("processes a DM and sends reply", async () => {

View File

@@ -2,6 +2,7 @@ import { type RunOptions, run } from "@grammyjs/runner";
import { resolveAgentMaxConcurrent } from "../config/agent-limits.js";
import type { OpenClawConfig } from "../config/config.js";
import { loadConfig } from "../config/config.js";
import { waitForAbortSignal } from "../infra/abort-signal.js";
import { computeBackoff, sleepWithAbort } from "../infra/backoff.js";
import { formatErrorMessage } from "../infra/errors.js";
import { formatDurationPrecise } from "../infra/format-time/format-duration.ts";
@@ -172,16 +173,7 @@ export async function monitorTelegramProvider(opts: MonitorTelegramOpts = {}) {
abortSignal: opts.abortSignal,
publicUrl: opts.webhookUrl,
});
const abortSignal = opts.abortSignal;
if (abortSignal && !abortSignal.aborted) {
await new Promise<void>((resolve) => {
const onAbort = () => {
abortSignal.removeEventListener("abort", onAbort);
resolve();
};
abortSignal.addEventListener("abort", onAbort, { once: true });
});
}
await waitForAbortSignal(opts.abortSignal);
return;
}