diff --git a/src/contact.rs b/src/contact.rs index c4bf4462ee..ca73060a7f 100644 --- a/src/contact.rs +++ b/src/contact.rs @@ -37,7 +37,7 @@ use crate::mimeparser::AvatarAction; use crate::param::{Param, Params}; use crate::sync::{self, Sync::*}; use crate::tools::{SystemTime, duration_to_str, get_abs_path, time}; -use crate::{chat, chatlist_events, stock_str}; +use crate::{chat, chatlist_events, ensure_and_debug_assert_ne, stock_str}; /// Time during which a contact is considered as seen recently. const SEEN_RECENTLY_SECONDS: i64 = 600; @@ -1922,9 +1922,10 @@ pub(crate) async fn mark_contact_id_as_verified( contact_id: ContactId, verifier_id: ContactId, ) -> Result<()> { - debug_assert_ne!( - contact_id, verifier_id, - "Contact cannot be verified by self" + ensure_and_debug_assert_ne!( + contact_id, + verifier_id, + "Contact cannot be verified by self", ); context .sql diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 8baa0ded9a..0a4c266f90 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -20,6 +20,7 @@ use crate::constants::{Chattype, DC_FROM_HANDSHAKE}; use crate::contact::{Contact, ContactId, Origin}; use crate::context::Context; use crate::e2ee::EncryptHelper; +use crate::ensure_and_debug_assert; use crate::ephemeral::Timer as EphemeralTimer; use crate::key::self_fingerprint; use crate::key::{DcKey, SignedPublicKey}; @@ -308,7 +309,7 @@ impl MimeFactory { } else if id == ContactId::SELF { member_fingerprints.push(self_fingerprint.to_string()); } else { - debug_assert!(member_fingerprints.is_empty(), "If some past member is a key-contact, all other past members should be key-contacts too"); + ensure_and_debug_assert!(member_fingerprints.is_empty(), "If some past member is a key-contact, all other past members should be key-contacts too"); } } member_timestamps.push(add_timestamp); @@ -359,7 +360,7 @@ impl MimeFactory { // if we are leaving the group. past_member_fingerprints.push(self_fingerprint.to_string()); } else { - debug_assert!(past_member_fingerprints.is_empty(), "If some past member is a key-contact, all other past members should be key-contacts too"); + ensure_and_debug_assert!(past_member_fingerprints.is_empty(), "If some past member is a key-contact, all other past members should be key-contacts too"); } } } @@ -367,8 +368,8 @@ impl MimeFactory { } } - debug_assert!(member_timestamps.len() >= to.len()); - debug_assert!(member_fingerprints.is_empty() || member_fingerprints.len() >= to.len()); + ensure_and_debug_assert!(member_timestamps.len() >= to.len()); + ensure_and_debug_assert!(member_fingerprints.is_empty() || member_fingerprints.len() >= to.len()); if to.len() > 1 { if let Some(position) = to.iter().position(|(_, x)| x == &from_addr) { @@ -445,7 +446,7 @@ impl MimeFactory { }; let attach_selfavatar = Self::should_attach_selfavatar(context, &msg).await; - debug_assert!( + ensure_and_debug_assert!( member_timestamps.is_empty() || to.len() + past_members.len() == member_timestamps.len() ); @@ -668,7 +669,7 @@ impl MimeFactory { )); } - debug_assert!( + ensure_and_debug_assert!( self.member_timestamps.is_empty() || to.len() + past_members.len() == self.member_timestamps.len() ); diff --git a/src/receive_imf.rs b/src/receive_imf.rs index 131167ad9f..b4993aad69 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -42,7 +42,7 @@ use crate::simplify; use crate::stock_str; use crate::sync::Sync::*; use crate::tools::{self, buf_compress, remove_subject_prefix}; -use crate::{chatlist_events, location}; +use crate::{chatlist_events, ensure_and_debug_assert, ensure_and_debug_assert_eq, location}; use crate::{contact, imap}; /// This is the struct that is returned after receiving one email (aka MIME message). @@ -1454,7 +1454,7 @@ async fn do_chat_assignment( false => None, }; if let Some(chat) = chat { - debug_assert!(chat.typ == Chattype::Single); + ensure_and_debug_assert!(chat.typ == Chattype::Single); let mut new_protection = match verified_encryption { VerifiedEncryption::Verified => ProtectionStatus::Protected, VerifiedEncryption::NotVerified(_) => ProtectionStatus::Unprotected, @@ -2137,7 +2137,7 @@ RETURNING id // afterwards insert additional parts. replace_msg_id = None; - debug_assert!(!row_id.is_special()); + ensure_and_debug_assert!(!row_id.is_special()); created_db_entries.push(row_id); } @@ -2400,7 +2400,9 @@ async fn lookup_chat_by_reply( // lookup by reply should never be needed // as we can directly assign the message to the chat // by its group ID. - debug_assert!(mime_parser.get_chat_group_id().is_none() || !mime_parser.was_encrypted()); + ensure_and_debug_assert!( + mime_parser.get_chat_group_id().is_none() || !mime_parser.was_encrypted() + ); // Try to assign message to the same chat as the parent message. let Some(parent_chat_id) = ChatId::lookup_by_message(parent) else { @@ -3727,7 +3729,7 @@ async fn add_or_lookup_key_contacts_by_address_list( } } - debug_assert_eq!(contact_ids.len(), address_list.len()); + ensure_and_debug_assert_eq!(contact_ids.len(), address_list.len(),); Ok(contact_ids) } @@ -3881,7 +3883,7 @@ async fn lookup_key_contacts_by_address_list( contact_ids.push(contact_id); } } - debug_assert_eq!(address_list.len(), contact_ids.len()); + ensure_and_debug_assert_eq!(address_list.len(), contact_ids.len(),); Ok(contact_ids) } diff --git a/src/tools.rs b/src/tools.rs index e7b91aacec..cb37bdeee8 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -763,5 +763,43 @@ pub(crate) fn inc_and_check( Ok(()) } +/// Returns early with an error if a condition is not satisfied. +/// In non-optimized builds, panics instead if so. +#[macro_export] +macro_rules! ensure_and_debug_assert { + ($($arg:tt)*) => { + debug_assert!($($arg)*); + anyhow::ensure!($($arg)*); + }; +} + +/// Returns early with an error on two expressions inequality. +/// In non-optimized builds, panics instead if so. +#[macro_export] +macro_rules! ensure_and_debug_assert_eq { + ($left:expr, $right:expr, $($arg:tt)*) => { + match (&$left, &$right) { + (left_val, right_val) => { + debug_assert_eq!(left_val, right_val, $($arg)*); + anyhow::ensure!(left_val == right_val, $($arg)*); + } + } + }; +} + +/// Returns early with an error on two expressions equality. +/// In non-optimized builds, panics instead if so. +#[macro_export] +macro_rules! ensure_and_debug_assert_ne { + ($left:expr, $right:expr, $($arg:tt)*) => { + match (&$left, &$right) { + (left_val, right_val) => { + debug_assert_ne!(left_val, right_val, $($arg)*); + anyhow::ensure!(left_val != right_val, $($arg)*); + } + } + }; +} + #[cfg(test)] mod tools_tests;