fix(tasks): avoid leaking scheduled sweep failures

This commit is contained in:
Vincent Koc
2026-04-13 16:26:55 +01:00
parent a945605b3c
commit 6a8704cf26
2 changed files with 52 additions and 2 deletions

View File

@@ -286,9 +286,10 @@ function startScheduledSweep() {
return;
}
sweepInProgress = true;
void sweepTaskRegistry().finally(() => {
const clearSweepInProgress = () => {
sweepInProgress = false;
});
};
sweepTaskRegistry().then(clearSweepInProgress, clearSweepInProgress);
}
export async function runTaskRegistryMaintenance(): Promise<TaskRegistryMaintenanceSummary> {

View File

@@ -1453,6 +1453,55 @@ describe("task-registry", () => {
});
});
it("does not leak unhandled rejections when the scheduled maintenance sweep fails", async () => {
await withTaskRegistryTempDir(async (root) => {
vi.useFakeTimers();
process.env.OPENCLAW_STATE_DIR = root;
resetTaskRegistryForTests();
const unhandled: unknown[] = [];
const onUnhandledRejection = (reason: unknown) => {
unhandled.push(reason);
};
process.on("unhandledRejection", onUnhandledRejection);
setTaskRegistryMaintenanceRuntimeForTests({
readAcpSessionEntry: () => ({
cfg: {} as never,
storePath: "",
sessionKey: "",
storeSessionKey: "",
entry: undefined,
storeReadFailed: false,
}),
loadSessionStore: () => ({}),
resolveStorePath: () => "",
parseAgentSessionKey: () => null,
isCronJobActive: () => false,
getAgentRunContext: () => undefined,
deleteTaskRecordById: () => false,
ensureTaskRegistryReady: () => {},
getTaskById: () => undefined,
listTaskRecords: () => {
throw new Error("maintenance boom");
},
markTaskLostById: () => null,
maybeDeliverTaskTerminalUpdate: async () => null,
resolveTaskForLookupToken: () => undefined,
setTaskCleanupAfterById: () => null,
});
try {
startTaskRegistryMaintenance();
await vi.advanceTimersByTimeAsync(5_000);
await flushAsyncWork();
expect(unhandled).toEqual([]);
} finally {
process.off("unhandledRejection", onUnhandledRejection);
}
});
});
it("rechecks current task state before marking a task lost", async () => {
const now = Date.now();
const snapshotTask = createTaskRecord({