From 650c5cac3326434ccd2ec47e91982da1005eb285 Mon Sep 17 00:00:00 2001 From: zhang-guiping Date: Sun, 14 Jun 2026 11:13:56 +0800 Subject: [PATCH] fix(qqbot): surface failed media sends (#92823) * fix(qqbot): surface media send failures * test(qqbot): cover text send failures --------- Co-authored-by: Vincent Koc --- .../qqbot/src/channel.message-adapter.test.ts | 50 +++++++++++++++++++ extensions/qqbot/src/channel.ts | 8 ++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/extensions/qqbot/src/channel.message-adapter.test.ts b/extensions/qqbot/src/channel.message-adapter.test.ts index f49f44dc88c2..fc3f1260ace3 100644 --- a/extensions/qqbot/src/channel.message-adapter.test.ts +++ b/extensions/qqbot/src/channel.message-adapter.test.ts @@ -114,4 +114,54 @@ describe("qqbot message adapter", () => { expect(proofResults.find((result) => result.capability === "media")?.status).toBe("verified"); expect(proofResults.find((result) => result.capability === "replyTo")?.status).toBe("verified"); }); + + it("rejects media sends when QQBot reports an outbound error", async () => { + sendMediaMock.mockResolvedValue({ error: "QQ API returned 400 Bad Request" }); + + await expect( + qqbotPlugin.message?.send?.media?.({ + cfg, + to: "qqbot:c2c:user-1", + text: "image", + mediaUrl: "https://example.com/image.png", + }), + ).rejects.toThrow("QQ API returned 400 Bad Request"); + }); + + it("rejects text sends when QQBot reports an outbound error", async () => { + sendTextMock.mockResolvedValue({ error: "QQ API returned 400 Bad Request" }); + + await expect( + qqbotPlugin.message?.send?.text?.({ + cfg, + to: "qqbot:c2c:user-1", + text: "hello", + }), + ).rejects.toThrow("QQ API returned 400 Bad Request"); + }); + + it("rejects media sends without a QQ platform message id", async () => { + sendMediaMock.mockResolvedValue({}); + + await expect( + qqbotPlugin.message?.send?.media?.({ + cfg, + to: "qqbot:c2c:user-1", + text: "image", + mediaUrl: "https://example.com/image.png", + }), + ).rejects.toThrow("QQBot message adapter send did not return a platform message id"); + }); + + it("rejects text sends without a QQ platform message id", async () => { + sendTextMock.mockResolvedValue({}); + + await expect( + qqbotPlugin.message?.send?.text?.({ + cfg, + to: "qqbot:c2c:user-1", + text: "hello", + }), + ).rejects.toThrow("QQBot message adapter send did not return a platform message id"); + }); }); diff --git a/extensions/qqbot/src/channel.ts b/extensions/qqbot/src/channel.ts index db2e98896be5..b820b06b43d2 100644 --- a/extensions/qqbot/src/channel.ts +++ b/extensions/qqbot/src/channel.ts @@ -134,8 +134,14 @@ async function sendQQBotMedia(params: { } function toQQBotMessageSendResult(result: Awaited>) { + if (result.meta?.error) { + throw new Error(result.meta.error); + } + if (result.receipt.platformMessageIds.length === 0) { + throw new Error("QQBot message adapter send did not return a platform message id"); + } return { - messageId: result.messageId, + messageId: result.messageId || result.receipt.primaryPlatformMessageId, receipt: result.receipt, } satisfies ChannelMessageSendResult; }