mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-24 19:54:28 +00:00
fix: abort telegram getupdates on shutdown (#23950) (thanks @Gkinthecodeland)
This commit is contained in:
committed by
Vincent Koc
parent
e383257552
commit
2220a58ff7
@@ -75,27 +75,6 @@ describe("createTelegramBot", () => {
|
||||
globalThis.fetch = originalFetch;
|
||||
}
|
||||
});
|
||||
it("aborts wrapped client fetch when fetchAbortSignal aborts", async () => {
|
||||
const originalFetch = globalThis.fetch;
|
||||
const fetchSpy = vi.fn(async (_input: RequestInfo | URL, init?: RequestInit) => init?.signal);
|
||||
const shutdown = new AbortController();
|
||||
globalThis.fetch = fetchSpy as unknown as typeof fetch;
|
||||
try {
|
||||
createTelegramBot({ token: "tok", fetchAbortSignal: shutdown.signal });
|
||||
const clientFetch = (botCtorSpy.mock.calls[0]?.[1] as { client?: { fetch?: unknown } })
|
||||
?.client?.fetch as ((input: RequestInfo | URL, init?: RequestInit) => Promise<unknown>);
|
||||
expect(clientFetch).toBeTypeOf("function");
|
||||
|
||||
const observedSignal = (await clientFetch("https://example.test")) as AbortSignal;
|
||||
expect(observedSignal).toBeInstanceOf(AbortSignal);
|
||||
expect(observedSignal.aborted).toBe(false);
|
||||
|
||||
shutdown.abort(new Error("shutdown"));
|
||||
expect(observedSignal.aborted).toBe(true);
|
||||
} finally {
|
||||
globalThis.fetch = originalFetch;
|
||||
}
|
||||
});
|
||||
it("applies global and per-account timeoutSeconds", () => {
|
||||
loadConfig.mockReturnValue({
|
||||
channels: {
|
||||
|
||||
34
src/telegram/bot.fetch-abort.test.ts
Normal file
34
src/telegram/bot.fetch-abort.test.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { botCtorSpy } from "./bot.create-telegram-bot.test-harness.js";
|
||||
import { createTelegramBot } from "./bot.js";
|
||||
|
||||
describe("createTelegramBot fetch abort", () => {
|
||||
it("aborts wrapped client fetch when fetchAbortSignal aborts", async () => {
|
||||
const originalFetch = globalThis.fetch;
|
||||
const shutdown = new AbortController();
|
||||
const fetchSpy = vi.fn(
|
||||
(_input: RequestInfo | URL, init?: RequestInit) =>
|
||||
new Promise<AbortSignal>((resolve) => {
|
||||
const signal = init?.signal as AbortSignal;
|
||||
signal.addEventListener("abort", () => resolve(signal), { once: true });
|
||||
}),
|
||||
);
|
||||
globalThis.fetch = fetchSpy as unknown as typeof fetch;
|
||||
try {
|
||||
botCtorSpy.mockClear();
|
||||
createTelegramBot({ token: "tok", fetchAbortSignal: shutdown.signal });
|
||||
const clientFetch = (botCtorSpy.mock.calls.at(-1)?.[1] as { client?: { fetch?: unknown } })
|
||||
?.client?.fetch as (input: RequestInfo | URL, init?: RequestInit) => Promise<unknown>;
|
||||
expect(clientFetch).toBeTypeOf("function");
|
||||
|
||||
const observedSignalPromise = clientFetch("https://example.test");
|
||||
shutdown.abort(new Error("shutdown"));
|
||||
const observedSignal = (await observedSignalPromise) as AbortSignal;
|
||||
|
||||
expect(observedSignal).toBeInstanceOf(AbortSignal);
|
||||
expect(observedSignal.aborted).toBe(true);
|
||||
} finally {
|
||||
globalThis.fetch = originalFetch;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -110,8 +110,7 @@ export function createTelegramBot(opts: TelegramBotOptions) {
|
||||
// (especially long-polling getUpdates) aborts immediately on shutdown. Without this,
|
||||
// the in-flight getUpdates hangs for up to 30s, and a new gateway instance starting
|
||||
// its own poll triggers a 409 Conflict from Telegram.
|
||||
let finalFetch: NonNullable<ApiClientOptions["fetch"]> | undefined =
|
||||
shouldProvideFetch && fetchImpl ? fetchForClient : undefined;
|
||||
let finalFetch = shouldProvideFetch && fetchImpl ? fetchForClient : undefined;
|
||||
if (opts.fetchAbortSignal) {
|
||||
const baseFetch =
|
||||
finalFetch ?? (globalThis.fetch as unknown as NonNullable<ApiClientOptions["fetch"]>);
|
||||
|
||||
Reference in New Issue
Block a user