From 5737ba590c5c5bc366f559bcd984a25f84b6461d Mon Sep 17 00:00:00 2001 From: Renato Alcara Date: Sun, 26 Apr 2026 11:32:03 -0300 Subject: [PATCH] fix: preserve full Error for unknown decrypt failures + improve dedup comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses 3 distinct PR #391 review findings (Copilot Major + Codex P2 + Copilot nitpick — all valid): #2 Copilot Major + #4 Codex P2 (same root, MAJOR): The previous slim of `errorContext.err` to `{name, message, type}` was applied uniformly to all three decrypt-failure branches. The unknown-error branch (lines 481-491 — "Unknown/unexpected errors (protobuf, parsing, etc.)") is exactly where stack traces matter MOST: there's no recovery path for those, so production root-cause analysis depends on having the stack. FIX: condition `errorContext.err` on category. Only slim for known-recoverable categories (corrupted-session / session-record). Unknown errors keep the full originalError so logger.error pino still emits the stack. Adds the `isRecoverableCategory` flag to make the intent obvious to future readers. #3 Copilot (related to #2): The previous comment claimed "Full stack is still available via originalError if needed in custom handlers" — but originalError wasn't actually exposed anywhere downstream and the error wasn't re-thrown. Updated the comment to reflect the new conditional behavior (slim only for recoverable cases) so future maintainers don't misread the intent. #1 Copilot (dedup window comment, MINOR): The 5000ms dedup window in src/index.ts can suppress genuinely-different errors for the same JID within the window. Kept the 5s value (it's the right trade-off for noisy production streams) but expanded the comment to spell out the trade-off and how to bypass it (BAILEYS_LOG_LEVEL=debug). Skipped: nothing — all reviewer points addressed. Tests: 35/35 suites, 824/824 still passing. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/Utils/decode-wa-message.ts | 11 ++++++++--- src/index.ts | 9 +++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Utils/decode-wa-message.ts b/src/Utils/decode-wa-message.ts index 171338f7..5ebf5520 100644 --- a/src/Utils/decode-wa-message.ts +++ b/src/Utils/decode-wa-message.ts @@ -427,8 +427,12 @@ export const decryptMessageNode = ( // Slim error projection — keep name/message/type for diagnosis, // drop `stack` which adds 4-5 lines of node_modules paths per log - // for known-recoverable libsignal errors. Full stack is still - // available via originalError if needed in custom handlers. + // for known-recoverable libsignal errors. + // + // CRITICAL: only slim for KNOWN-RECOVERABLE categories (corrupted / + // session-record). The unknown-error branch keeps the full Error so + // protobuf/parsing/runtime bugs still emit a stack trace where it + // matters most. Catches Copilot/Codex P2 review on PR #391. const slimErr = originalError ? { name: (originalError as { name?: string }).name, @@ -436,10 +440,11 @@ export const decryptMessageNode = ( type: (originalError as { type?: string }).type } : undefined + const isRecoverableCategory = isCorrupted || isSessionRecord const errorContext = { key: fullMessage.key, - err: slimErr, + err: isRecoverableCategory ? slimErr : originalError, messageType: tag === 'plaintext' ? 'plaintext' : attrs.type, sender, author, diff --git a/src/index.ts b/src/index.ts index 745af59f..fc3a701c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -30,8 +30,13 @@ console.info = function (...args: unknown[]) { const _errorTimestamps = new Map() // Dedup window for repeated decrypt-error console lines (Bad MAC / Counter / etc). // Was 150ms, but retry attempts of the SAME message are typically ~300-1000ms apart, -// so the second attempt fell outside the window and double-printed. 5s comfortably -// covers a retry pair without suppressing genuinely new errors for the same JID. +// so the second attempt fell outside the window and double-printed. +// +// TRADE-OFF: dedup key is `errorType + JID` (no message-id). With 5s, a burst of +// errors for the SAME JID — even of slightly different categories or different +// messages — collapses to one log line every 5s. This is intentional for a noisy +// production stream; if you need per-message visibility, set BAILEYS_LOG_LEVEL=debug +// to bypass this console-side dedup and see the structured pino logs in full. const DEDUP_WINDOW_MS = 5000 console.error = function (...args: unknown[]) {