mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:20:43 +00:00
fix: flush creds queue before reconnect socket open (#67464) (thanks @neeravmakwana)
* WhatsApp: flush creds queue before reconnect socket open * fix: flush creds queue before reconnect socket open (#67464) (thanks @neeravmakwana) --------- Co-authored-by: Ayaan Zaidi <hi@obviy.us>
This commit is contained in:
@@ -26,6 +26,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Dashboard: constrain exec approval modal overflow on desktop so long command content no longer pushes action buttons out of view. (#67082) Thanks @Ziy1-Tan.
|
||||
- Agents/CLI transcripts: persist successful CLI-backed turns into the OpenClaw session transcript so google-gemini-cli replies appear in session history and the Control UI again. (#67490) Thanks @obviyus.
|
||||
- Discord/tool-call text: strip standalone Gemma-style `<function>...</function>` tool-call payloads from visible assistant text without truncating prose examples or trailing replies. (#67318) Thanks @joelnishanth.
|
||||
- WhatsApp/web-session: drain the pending per-auth creds save queue before reopening sockets so reconnect-time auth bootstrap no longer races in-flight `creds.json` writes and falsely restores from backup. (#67464) Thanks @neeravmakwana.
|
||||
|
||||
## 2026.4.15-beta.1
|
||||
|
||||
|
||||
@@ -1,20 +1,35 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { getRegisteredWhatsAppConnectionController } from "./connection-controller-registry.js";
|
||||
import { WhatsAppConnectionController } from "./connection-controller.js";
|
||||
import { createWaSocket, waitForWaConnection } from "./session.js";
|
||||
import {
|
||||
createWaSocket,
|
||||
waitForCredsSaveQueueWithTimeout,
|
||||
waitForWaConnection,
|
||||
} from "./session.js";
|
||||
|
||||
vi.mock("./session.js", async () => {
|
||||
const actual = await vi.importActual<typeof import("./session.js")>("./session.js");
|
||||
return {
|
||||
...actual,
|
||||
createWaSocket: vi.fn(),
|
||||
waitForCredsSaveQueueWithTimeout: vi.fn(async () => {}),
|
||||
waitForWaConnection: vi.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
const createWaSocketMock = vi.mocked(createWaSocket);
|
||||
const waitForCredsSaveQueueWithTimeoutMock = vi.mocked(waitForCredsSaveQueueWithTimeout);
|
||||
const waitForWaConnectionMock = vi.mocked(waitForWaConnection);
|
||||
|
||||
function createListenerStub(messageId = "ok") {
|
||||
return {
|
||||
sendMessage: vi.fn(async () => ({ messageId })),
|
||||
sendPoll: vi.fn(async () => ({ messageId })),
|
||||
sendReaction: vi.fn(async () => {}),
|
||||
sendComposingTo: vi.fn(async () => {}),
|
||||
};
|
||||
}
|
||||
|
||||
describe("WhatsAppConnectionController", () => {
|
||||
let controller: WhatsAppConnectionController;
|
||||
|
||||
@@ -66,6 +81,26 @@ describe("WhatsAppConnectionController", () => {
|
||||
expect(controller.getActiveListener()).toBeNull();
|
||||
});
|
||||
|
||||
it("flushes pending creds saves before opening a socket", async () => {
|
||||
const callOrder: string[] = [];
|
||||
waitForCredsSaveQueueWithTimeoutMock.mockImplementationOnce(async () => {
|
||||
callOrder.push("wait");
|
||||
});
|
||||
createWaSocketMock.mockImplementationOnce(async () => {
|
||||
callOrder.push("create");
|
||||
return { ws: { close: vi.fn() } } as never;
|
||||
});
|
||||
waitForWaConnectionMock.mockResolvedValueOnce(undefined);
|
||||
|
||||
await controller.openConnection({
|
||||
connectionId: "conn-flush-first",
|
||||
createListener: async () => createListenerStub() as never,
|
||||
});
|
||||
|
||||
expect(waitForCredsSaveQueueWithTimeoutMock).toHaveBeenCalledWith("/tmp/wa-auth");
|
||||
expect(callOrder).toEqual(["wait", "create"]);
|
||||
});
|
||||
|
||||
it("keeps the previous registered controller until a replacement listener is ready", async () => {
|
||||
const liveController = new WhatsAppConnectionController({
|
||||
accountId: "work",
|
||||
@@ -83,12 +118,7 @@ describe("WhatsAppConnectionController", () => {
|
||||
maxAttempts: 5,
|
||||
},
|
||||
});
|
||||
const liveListener = {
|
||||
sendMessage: vi.fn(async () => ({ messageId: "live-msg" })),
|
||||
sendPoll: vi.fn(async () => ({ messageId: "live-poll" })),
|
||||
sendReaction: vi.fn(async () => {}),
|
||||
sendComposingTo: vi.fn(async () => {}),
|
||||
};
|
||||
const liveListener = createListenerStub("live");
|
||||
createWaSocketMock.mockResolvedValueOnce({ ws: { close: vi.fn() } } as never);
|
||||
waitForWaConnectionMock.mockResolvedValueOnce(undefined);
|
||||
await liveController.openConnection({
|
||||
|
||||
@@ -347,6 +347,7 @@ export class WhatsAppConnectionController {
|
||||
let sock: WaSocket | null = null;
|
||||
let connection: WhatsAppLiveConnection | null = null;
|
||||
try {
|
||||
await waitForCredsSaveQueueWithTimeout(this.authDir);
|
||||
sock = await createWaSocket(false, this.verbose, {
|
||||
authDir: this.authDir,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user