fix(whatsapp): keep opening text chunk when first media fails on multi-chunk reply

When a WhatsApp auto-reply spans more than one chunk and is sent with an image
whose send fails, the first chunk was silently dropped. The first-media onError
fallback evaluated remainingText.shift() before the caption, so on a multi-chunk
reply the truthy second chunk discarded the caption that held the opening chunk.
Resurface the caption directly; the trailing loop already sends the rest.

Adds a regression test driving deliverWebReply with a two-chunk reply and a
failing first media send.
This commit is contained in:
yetval
2026-06-17 00:36:55 +00:00
parent 4d3e355a52
commit b609e44654
2 changed files with 27 additions and 1 deletions

View File

@@ -624,6 +624,32 @@ describe("deliverWebReply", () => {
expect(warnContext.mediaUrl).toBe("http://example.com/img.jpg");
});
it("delivers the opening text chunk when the first media fails on a multi-chunk reply", async () => {
const msg = makeMsg();
mockLoadedImageMedia();
mockFirstSendMediaFailure(msg, "boom");
await deliverWebReply({
replyResult: { text: "ALPHALINEBRAVOLINE", mediaUrl: "http://example.com/img.jpg" },
msg,
maxMediaBytes: 1024 * 1024,
textLimit: 9,
replyLogger,
skipLog: true,
});
expect(replyText(msg, 0)).toContain("ALPHALINE");
expect(replyText(msg, 0)).toContain("⚠️ Media failed");
const allReplies = (
msg.platform.reply as unknown as { mock: { calls: unknown[][] } }
).mock.calls
.map((call) => String(call[0]))
.join("\n");
expect(allReplies).toContain("ALPHALINE");
expect(allReplies).toContain("BRAVOLINE");
expect(allReplies).not.toContain("boom");
});
it("still attempts later media after the first media fails", async () => {
vi.clearAllMocks();
const msg = makeMsg();

View File

@@ -340,7 +340,7 @@ export async function deliverWebReply(params: {
return;
}
const warning = "⚠️ Media failed.";
const fallbackTextParts = [remainingText.shift() ?? caption ?? "", warning].filter(Boolean);
const fallbackTextParts = [caption ?? "", warning].filter(Boolean);
const fallbackText = fallbackTextParts.join("\n");
if (!fallbackText) {
return;