fix(send): fail DM send when every per-device encrypt fails - #652
Conversation
prepare_dm_stanza built an empty <participants> stanza and returned Ok when encrypt_for_devices skipped every recipient device (e.g. all bundles missing), silently dropping the message with no error and no retry. WA Web encryptAndSendUserMsg rejects with "encryption fail for all devices". Mirror that: return Err when participant_nodes is empty but there were recipient devices, so the caller's error path fires. Note: the all-fail path needs the full Signal store adapter (src/), so a dedicated unit test belongs at integration level; the guard itself is a minimal invariant verified by reading the fanout path.
|
Warning Review limit reached
More reviews will be available in 11 minutes and 34 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough
ChangesDM Send Error Handling
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Possibly related PRs
Suggested labels
Look, this is exactly the kind of thing that needs to happen. We can't have messages silently disappearing because encryption failed. Either it works or the user knows it doesn't work—there's no in-between. The guard is tight, focused, and prevents a real class of bugs. Ships cleanly. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d1a7584bf7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Actionable comments posted: 0 |
Benchmark Results67 unchanged benchmark(s)
|
total_devices counted the own sending device too (excluded by partition_dm_devices), so the error count was off by one. Base the empty fanout check on the devices actually encrypted for.
Finding (WA Web parity audit, area: send/encrypt)
prepare_dm_stanza(wacore/src/send.rs) extendsparticipant_nodesfromencrypt_for_devices, which logs+skips each device whose encryption fails (missing prekey bundle, etc.) and returnsOkwith whatever succeeded. When ALL recipient devices fail,participant_nodesis empty, yet the code unconditionally built<participants>and returnedOk— shipping an empty stanza and reporting success. The message is silently dropped with no error and no retry trigger.WA Web
WAWebSendMsgCreateFanoutStanza(encryptAndSendUserMsg) rejects withencryption fail for all deviceswhen the per-device encrypt set is empty.Change
Return
Errwhenparticipant_nodes.is_empty() && total_devices > 0, mirroring WA Web. Only the all-fail case changes (previously a silent no-op); partial success is unaffected.Testing
cargo build -p wacore,cargo clippy -p wacore --tests,cargo test -p wacore(send tests pass). The all-fail path requires the full Signal store adapter (src/), so a dedicated test belongs at integration level; the guard is a minimal invariant verified by reading the fanout path.Draft — one of several from a WA Web parity audit; review independently.