fix(channels): improve health metadata and reply diagnostics

This commit is contained in:
Peter Steinberger
2026-04-29 16:27:14 +01:00
parent 1390eadd92
commit 4dd2768c4b
6 changed files with 432 additions and 106 deletions

View File

@@ -118,6 +118,16 @@ function getCapturedDeliver() {
)?.dispatcherOptions?.deliver;
}
function getCapturedOnError() {
return (
capturedDispatchParams as {
dispatcherOptions?: {
onError?: (err: unknown, info: { kind: "tool" | "block" | "final" }) => void;
};
}
)?.dispatcherOptions?.onError;
}
type BufferedReplyParams = Parameters<typeof dispatchWhatsAppBufferedReply>[0];
function makeReplyLogger(): BufferedReplyParams["replyLogger"] {
@@ -704,6 +714,44 @@ describe("whatsapp inbound dispatch", () => {
).toBe(sendComposing);
});
it("logs delivery failures from the shared dispatcher with WhatsApp context", async () => {
const replyLogger = {
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
debug: vi.fn(),
} as BufferedReplyParams["replyLogger"];
const error = new Error("send failed");
await dispatchBufferedReply({
connectionId: "conn-1",
conversationId: "+15550001000",
msg: makeMsg({
id: "msg-1",
from: "+15550001000",
to: "+15550002000",
chatId: "15550001000@s.whatsapp.net",
}),
replyLogger,
});
getCapturedOnError()?.(error, { kind: "final" });
expect(replyLogger.error).toHaveBeenCalledWith(
{
err: error,
replyKind: "final",
correlationId: "msg-1",
connectionId: "conn-1",
conversationId: "+15550001000",
chatId: "15550001000@s.whatsapp.net",
to: "+15550001000",
from: "+15550002000",
},
"auto-reply delivery failed",
);
});
it("updates main last route for DM when session key matches main session key", () => {
const updateLastRoute = vi.fn();

View File

@@ -56,6 +56,29 @@ type SenderContext = {
e164?: string;
};
function logWhatsAppReplyDeliveryError(params: {
err: unknown;
info: { kind: ReplyLifecycleKind };
connectionId: string;
conversationId: string;
msg: WebInboundMsg;
replyLogger: ReturnType<typeof getChildLogger>;
}) {
params.replyLogger.error(
{
err: params.err,
replyKind: params.info.kind,
correlationId: params.msg.id ?? null,
connectionId: params.connectionId,
conversationId: params.conversationId,
chatId: params.msg.chatId ?? null,
to: params.msg.from ?? null,
from: params.msg.to ?? null,
},
"auto-reply delivery failed",
);
}
function resolveWhatsAppDisableBlockStreaming(cfg: ReturnType<LoadConfigFn>): boolean | undefined {
if (typeof cfg.channels?.whatsapp?.blockStreaming !== "boolean") {
return undefined;
@@ -355,6 +378,16 @@ export async function dispatchWhatsAppBufferedReply(params: {
}
},
onReplyStart: params.msg.sendComposing,
onError: (err, info) => {
logWhatsAppReplyDeliveryError({
err,
info,
connectionId: params.connectionId,
conversationId: params.conversationId,
msg: params.msg,
replyLogger: params.replyLogger,
});
},
},
replyOptions: {
disableBlockStreaming,