From b52183b00062f3777038f35e3cd618153d11c565 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Fri, 22 Nov 2024 13:45:15 -0800 Subject: [PATCH] backup: Include the timestamp of a ChatItem on error --- rust/message-backup/src/backup.rs | 23 +++++++++++++++---- rust/message-backup/src/backup/chat.rs | 7 ++++-- rust/message-backup/src/backup/time.rs | 15 ++++++++---- .../group-update-invalid-aci.jsonproto | 1 + ...roup-update-invalid-aci.jsonproto.expected | 2 +- .../invalid/sticker-pack-id.jsonproto | 1 + .../sticker-pack-id.jsonproto.expected | 2 +- 7 files changed, 38 insertions(+), 13 deletions(-) diff --git a/rust/message-backup/src/backup.rs b/rust/message-backup/src/backup.rs index a60a39241..113364cb7 100644 --- a/rust/message-backup/src/backup.rs +++ b/rust/message-backup/src/backup.rs @@ -469,10 +469,19 @@ impl PartialBackup { fn add_chat_item(&mut self, chat_item: proto::ChatItem) -> Result<(), ValidationError> { let chat_id = ChatId(chat_item.chatId); + let raw_timestamp = chat_item.dateSent; let chat_item_data = chat_item .try_into_with(self) - .map_err(|e: ChatItemError| ChatFrameError(chat_id, e.into()))?; + .map_err(|error: ChatItemError| { + ChatFrameError( + chat_id, + ChatError::ChatItem { + raw_timestamp, + error, + }, + ) + })?; Ok(self.chats.add_chat_item(chat_id, chat_item_data)?) } @@ -527,9 +536,15 @@ impl ChatsData { pinned: _, } = self; - let chat_data = items - .get_mut(&chat_id) - .ok_or(ChatFrameError(chat_id, ChatItemError::NoChatForItem.into()))?; + let chat_data = items.get_mut(&chat_id).ok_or_else(|| { + ChatFrameError( + chat_id, + ChatError::ChatItem { + raw_timestamp: item.sent_at.as_millis(), + error: ChatItemError::NoChatForItem, + }, + ) + })?; item.total_chat_item_order_index = *chat_items_count; diff --git a/rust/message-backup/src/backup/chat.rs b/rust/message-backup/src/backup/chat.rs index a7503d14f..b1579211e 100644 --- a/rust/message-backup/src/backup/chat.rs +++ b/rust/message-backup/src/backup/chat.rs @@ -76,8 +76,11 @@ pub enum ChatError { InvalidRecipient(RecipientId, DestinationKind), /// chat with {0:?} has an expirationTimerMs but no expireTimerVersion MissingExpireTimerVersion(RecipientId), - /// chat item: {0} - ChatItem(#[from] ChatItemError), + /// chat item {raw_timestamp}: {error} + ChatItem { + raw_timestamp: u64, + error: ChatItemError, + }, /// {0:?} already appeared DuplicatePinnedOrder(PinOrder), /// style error: {0} diff --git a/rust/message-backup/src/backup/time.rs b/rust/message-backup/src/backup/time.rs index 5a2ed48bf..a45b1b60b 100644 --- a/rust/message-backup/src/backup/time.rs +++ b/rust/message-backup/src/backup/time.rs @@ -88,6 +88,15 @@ impl Timestamp { pub(super) fn into_inner(self) -> SystemTime { self.0 } + + pub fn as_millis(&self) -> u64 { + self.0 + .duration_since(UNIX_EPOCH) + .expect("should not be possible to construct a Timestamp older than UNIX_EPOCH") + .as_millis() + .try_into() + .expect("should not be possible to construct a Timestamp that requires u128 millis since UNIX_EPOCH") + } } impl serde::Serialize for Timestamp { @@ -95,11 +104,7 @@ impl serde::Serialize for Timestamp { where S: serde::Serializer, { - let offset = self - .0 - .duration_since(UNIX_EPOCH) - .expect("should not be possible to construct a Timestamp older than UNIX_EPOCH"); - serde::Serialize::serialize(&Duration(offset), serializer) + self.as_millis().serialize(serializer) } } diff --git a/rust/message-backup/tests/res/test-cases/invalid/group-update-invalid-aci.jsonproto b/rust/message-backup/tests/res/test-cases/invalid/group-update-invalid-aci.jsonproto index 853162352..e695c44f4 100644 --- a/rust/message-backup/tests/res/test-cases/invalid/group-update-invalid-aci.jsonproto +++ b/rust/message-backup/tests/res/test-cases/invalid/group-update-invalid-aci.jsonproto @@ -29,6 +29,7 @@ "chatItem": { "chatId": "1", "authorId": "1", + "dateSent": 12345, "directionless": {}, "updateMessage": { "groupChange": { diff --git a/rust/message-backup/tests/res/test-cases/invalid/group-update-invalid-aci.jsonproto.expected b/rust/message-backup/tests/res/test-cases/invalid/group-update-invalid-aci.jsonproto.expected index 519a70575..7a8afcfe2 100644 --- a/rust/message-backup/tests/res/test-cases/invalid/group-update-invalid-aci.jsonproto.expected +++ b/rust/message-backup/tests/res/test-cases/invalid/group-update-invalid-aci.jsonproto.expected @@ -1 +1 @@ -chat frame ChatId(1) error: chat item: group update: group update: SelfInvitedToGroupUpdate.inviterAci: invalid ACI \ No newline at end of file +chat frame ChatId(1) error: chat item 12345: group update: group update: SelfInvitedToGroupUpdate.inviterAci: invalid ACI \ No newline at end of file diff --git a/rust/message-backup/tests/res/test-cases/invalid/sticker-pack-id.jsonproto b/rust/message-backup/tests/res/test-cases/invalid/sticker-pack-id.jsonproto index a7ca46944..7bad1f25d 100644 --- a/rust/message-backup/tests/res/test-cases/invalid/sticker-pack-id.jsonproto +++ b/rust/message-backup/tests/res/test-cases/invalid/sticker-pack-id.jsonproto @@ -21,6 +21,7 @@ "chatId": "1", "authorId": "1", "directionless": {}, + "dateSent": 12345, "stickerMessage": { "sticker": { "packId": "YXNkZgo=", diff --git a/rust/message-backup/tests/res/test-cases/invalid/sticker-pack-id.jsonproto.expected b/rust/message-backup/tests/res/test-cases/invalid/sticker-pack-id.jsonproto.expected index b3b97d424..02aa52ea0 100644 --- a/rust/message-backup/tests/res/test-cases/invalid/sticker-pack-id.jsonproto.expected +++ b/rust/message-backup/tests/res/test-cases/invalid/sticker-pack-id.jsonproto.expected @@ -1 +1 @@ -chat frame ChatId(1) error: chat item: sticker message: pack ID is invalid \ No newline at end of file +chat frame ChatId(1) error: chat item 12345: sticker message: pack ID is invalid \ No newline at end of file