Author: Manos Pitsidianakis [manos@pitsidianak.is]
Hash: f7039e1997d9df7d82500be6ca97addef60e9baf
Timestamp: Wed, 10 Jan 2024 08:46:32 +0000 (8 months ago)

+20 -10 +/-2 browse
web: don't panic when calculating list posts
web: don't panic when calculating list posts

When going through a list's root messages, use filter_map() instead of
map() to avoid panicking in case the Envelope cannot be parsed or
there's a bug in the thread calculation.

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
1diff --git a/web/src/lists.rs b/web/src/lists.rs
2index ef99149..82b3bba 100644
3--- a/web/src/lists.rs
4+++ b/web/src/lists.rs
5 @@ -59,20 +59,30 @@ pub async fn list(
6 .collect::<HashMap<String, [usize; 31]>>();
7 let envelopes: Arc<std::sync::RwLock<HashMap<melib::EnvelopeHash, melib::Envelope>>> =
8 Default::default();
9- let mut env_lock = envelopes.write().unwrap();
10+ {
11+ let mut env_lock = envelopes.write().unwrap();
12
13- for post in &posts {
14- let envelope = melib::Envelope::from_bytes(post.message.as_slice(), None)
15- .expect("Could not parse mail");
16- env_lock.insert(envelope.hash(), envelope);
17+ for post in &posts {
18+ let Ok(mut envelope) = melib::Envelope::from_bytes(post.message.as_slice(), None)
19+ else {
20+ continue;
21+ };
22+ if envelope.message_id != post.message_id.as_str() {
23+ // If they don't match, the raw envelope doesn't contain a Message-ID and it was
24+ // randomly generated. So set the envelope's Message-ID to match the
25+ // post's, which is the "permanent" one since our source of truth is
26+ // the database.
27+ envelope.set_message_id(post.message_id.as_bytes());
28+ }
29+ env_lock.insert(envelope.hash(), envelope);
30+ }
31 }
32 let mut threads: melib::Threads = melib::Threads::new(posts.len());
33- drop(env_lock);
34 threads.amend(&envelopes);
35 let roots = thread_roots(&envelopes, &threads);
36 let posts_ctx = roots
37 .into_iter()
38- .map(|(thread, length, _timestamp)| {
39+ .filter_map(|(thread, length, _timestamp)| {
40 let post = &post_map[&thread.message_id.as_str()];
41 //2019-07-14T14:21:02
42 if let Some(day) =
43 @@ -82,8 +92,7 @@ pub async fn list(
44 {
45 hist.get_mut(&post.month_year).unwrap()[day.saturating_sub(1) as usize] += 1;
46 }
47- let envelope = melib::Envelope::from_bytes(post.message.as_slice(), None)
48- .expect("Could not parse mail");
49+ let envelope = melib::Envelope::from_bytes(post.message.as_slice(), None).ok()?;
50 let mut msg_id = &post.message_id[1..];
51 msg_id = &msg_id[..msg_id.len().saturating_sub(1)];
52 let subject = envelope.subject();
53 @@ -106,7 +115,7 @@ pub async fn list(
54 replies => length.saturating_sub(1),
55 last_active => thread.datetime,
56 };
57- ret
58+ Some(ret)
59 })
60 .collect::<Vec<_>>();
61 let crumbs = vec![
62 diff --git a/web/src/utils.rs b/web/src/utils.rs
63index 18a43b5..60217ee 100644
64--- a/web/src/utils.rs
65+++ b/web/src/utils.rs
66 @@ -290,6 +290,7 @@ where
67 .serialize(ser)
68 }
69
70+ #[derive(Debug, Clone)]
71 pub struct ThreadEntry {
72 pub hash: melib::EnvelopeHash,
73 pub depth: usize,