mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 13:50:49 +00:00
fix(runtime): avoid leaking detached cleanup promises
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { trackBackgroundTask } from "./last-route.js";
|
||||
|
||||
const waitForAsyncCallbacks = async () => {
|
||||
await Promise.resolve();
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
};
|
||||
|
||||
describe("trackBackgroundTask", () => {
|
||||
const unhandledRejections: unknown[] = [];
|
||||
const onUnhandledRejection = (reason: unknown) => {
|
||||
unhandledRejections.push(reason);
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
process.off("unhandledRejection", onUnhandledRejection);
|
||||
unhandledRejections.length = 0;
|
||||
});
|
||||
|
||||
it("does not leak unhandled rejections when a tracked task fails", async () => {
|
||||
process.on("unhandledRejection", onUnhandledRejection);
|
||||
const backgroundTasks = new Set<Promise<unknown>>();
|
||||
let rejectTask!: (reason?: unknown) => void;
|
||||
const task = new Promise<void>((_resolve, reject) => {
|
||||
rejectTask = reject;
|
||||
});
|
||||
|
||||
trackBackgroundTask(backgroundTasks, task);
|
||||
expect(backgroundTasks.size).toBe(1);
|
||||
|
||||
rejectTask(new Error("boom"));
|
||||
await waitForAsyncCallbacks();
|
||||
|
||||
expect(backgroundTasks.size).toBe(0);
|
||||
expect(unhandledRejections).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -9,9 +9,10 @@ export function trackBackgroundTask(
|
||||
task: Promise<unknown>,
|
||||
) {
|
||||
backgroundTasks.add(task);
|
||||
void task.finally(() => {
|
||||
const cleanup = () => {
|
||||
backgroundTasks.delete(task);
|
||||
});
|
||||
};
|
||||
task.then(cleanup, cleanup);
|
||||
}
|
||||
|
||||
export function updateLastRouteInBackground(params: {
|
||||
|
||||
Reference in New Issue
Block a user