fix(channels): add circuit breaker to typing keepalive loop

When the typing indicator start() call fails (e.g., message deleted,
API errors), the keepalive loop previously continued firing indefinitely.
This could trigger API rate limiting (e.g., Feishu 429) by sending
requests every 3 seconds for a resource that no longer exists.

Add a consecutive failure counter that stops the keepalive loop after
2 consecutive failures (configurable via maxConsecutiveFailures). The
counter resets on any successful call or when a new reply starts.
This commit is contained in:
YunhaoShui
2026-02-26 21:49:48 +08:00
committed by Peter Steinberger
parent b044c149c1
commit aa31f61c58

View File

@@ -117,6 +117,28 @@ describe("createTypingCallbacks", () => {
}
});
it("treats non-positive maxConsecutiveFailures as one failure", async () => {
vi.useFakeTimers();
try {
const start = vi.fn().mockRejectedValue(new Error("gone"));
const onStartError = vi.fn();
const callbacks = createTypingCallbacks({
start,
onStartError,
maxConsecutiveFailures: 0,
});
await callbacks.onReplyStart();
expect(start).toHaveBeenCalledTimes(1);
await vi.advanceTimersByTimeAsync(9_000);
expect(start).toHaveBeenCalledTimes(1);
expect(onStartError).toHaveBeenCalledTimes(1);
} finally {
vi.useRealTimers();
}
});
it("resets failure counter after a successful keepalive tick", async () => {
vi.useFakeTimers();
try {