fix(messages-recv): plain ack and error handling on early-ignore path

Addresses Codex P1 + Copilot + CodeRabbit review on PR #383:

1. Use plain sendMessageAck(node) for ignored messages — InfiniteAPI's
   prior in-handler check did NOT use NACK_REASONS.UnhandledError. The
   error code reports a processing failure and can trigger server-side
   retries; ignored stanzas are an intentional drop, not a failure.
   Restoring the original semantics.

2. Wrap the early-ignore block in try/catch routing to onUnexpectedError.
   shouldIgnoreJid is a user-provided callback and sendMessageAck can
   throw (e.g. websocket closed). Without this guard, the error becomes
   an unhandled promise rejection because the early path runs outside
   processNodeWithBuffer's catch wrapper.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Renato Alcara
2026-04-25 13:08:54 -03:00
parent fa7cc63846
commit c46889db43
+25 -13
View File
@@ -3091,21 +3091,33 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
// Fast path: ack and drop ignored JIDs before entering the buffer/queue.
// Skips type='call' so call events are never silently dropped via
// shouldIgnoreJid (preserves InfiniteAPI's pre-existing behavior).
// Wrapped in try/catch so a throw from shouldIgnoreJid (user callback)
// or sendMessageAck (e.g. websocket closed) is routed through
// onUnexpectedError instead of becoming an unhandled rejection —
// matches the protection processNodeWithBuffer provides.
if (type !== 'call') {
const from = node.attrs.from
let ignoreJid = from
if (type === 'receipt' && from) {
const attrs = node.attrs
const isLid = attrs.from!.includes('lid')
const isNodeFromMe = areJidsSameUser(
attrs.participant || attrs.from,
isLid ? authState.creds.me?.lid : authState.creds.me?.id
)
ignoreJid = !isNodeFromMe || isJidGroup(attrs.from) ? attrs.from : attrs.recipient
}
try {
const from = node.attrs.from
let ignoreJid = from
if (type === 'receipt' && from) {
const attrs = node.attrs
const isLid = attrs.from!.includes('lid')
const isNodeFromMe = areJidsSameUser(
attrs.participant || attrs.from,
isLid ? authState.creds.me?.lid : authState.creds.me?.id
)
ignoreJid = !isNodeFromMe || isJidGroup(attrs.from) ? attrs.from : attrs.recipient
}
if (ignoreJid && ignoreJid !== S_WHATSAPP_NET && shouldIgnoreJid(ignoreJid)) {
await sendMessageAck(node, type === 'message' ? NACK_REASONS.UnhandledError : undefined)
if (ignoreJid && ignoreJid !== S_WHATSAPP_NET && shouldIgnoreJid(ignoreJid)) {
// Plain ack (no NACK error code) preserves InfiniteAPI's prior
// behavior — ignored stanzas are an intentional drop, not a
// processing failure, so we don't want server-side retries.
await sendMessageAck(node)
return
}
} catch (error) {
onUnexpectedError(error as Error, identifier)
return
}
}