fix(outbound): fail media-only text-only adapter fallback

This commit is contained in:
Shakker
2026-03-04 18:39:38 +00:00
committed by Shakker
parent a970cae2da
commit 698c200eba
2 changed files with 50 additions and 1 deletions

View File

@@ -971,6 +971,53 @@ describe("deliverOutboundPayloads", () => {
expect(results).toEqual([{ channel: "matrix", messageId: "mx-2" }]);
});
it("fails media-only payloads when plugin outbound omits sendMedia", async () => {
hookMocks.runner.hasHooks.mockReturnValue(true);
const sendText = vi.fn().mockResolvedValue({ channel: "matrix", messageId: "mx-3" });
setActivePluginRegistry(
createTestRegistry([
{
pluginId: "matrix",
source: "test",
plugin: createOutboundTestPlugin({
id: "matrix",
outbound: { deliveryMode: "direct", sendText },
}),
},
]),
);
await expect(
deliverOutboundPayloads({
cfg: {},
channel: "matrix",
to: "!room:1",
payloads: [{ text: " ", mediaUrl: "https://example.com/file.png" }],
}),
).rejects.toThrow(
"Plugin outbound adapter does not implement sendMedia and no text fallback is available for media payload",
);
expect(sendText).not.toHaveBeenCalled();
expect(logMocks.warn).toHaveBeenCalledWith(
"Plugin outbound adapter does not implement sendMedia; media URLs will be dropped and text fallback will be used",
expect.objectContaining({
channel: "matrix",
mediaCount: 1,
}),
);
expect(hookMocks.runner.runMessageSent).toHaveBeenCalledWith(
expect.objectContaining({
to: "!room:1",
content: "",
success: false,
error:
"Plugin outbound adapter does not implement sendMedia and no text fallback is available for media payload",
}),
expect.objectContaining({ channelId: "matrix" }),
);
});
it("emits message_sent failure when delivery errors", async () => {
hookMocks.runner.hasHooks.mockReturnValue(true);
const sendWhatsApp = vi.fn().mockRejectedValue(new Error("downstream failed"));

View File

@@ -750,7 +750,9 @@ async function deliverOutboundPayloadsCore(
);
const fallbackText = payloadSummary.text.trim();
if (!fallbackText) {
continue;
throw new Error(
"Plugin outbound adapter does not implement sendMedia and no text fallback is available for media payload",
);
}
const beforeCount = results.length;
await sendTextChunks(fallbackText, sendOverrides);