diff --git a/src/chat.rs b/src/chat.rs index ab8263468..9baa7fdb1 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -2444,7 +2444,7 @@ pub(crate) async fn create_send_msg_job( let rendered_msg = match mimefactory.render(context).await { Ok(res) => Ok(res), Err(err) => { - message::set_msg_failed(context, msg.id, &err.to_string()).await?; + message::set_msg_failed(context, msg, &err.to_string()).await?; Err(err) } }?; @@ -2453,7 +2453,7 @@ pub(crate) async fn create_send_msg_job( /* unrecoverable */ message::set_msg_failed( context, - msg.id, + msg, "End-to-end-encryption unavailable unexpectedly.", ) .await?; diff --git a/src/message.rs b/src/message.rs index 03ccd70c2..0a299c3e9 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1667,30 +1667,33 @@ pub(crate) async fn update_msg_state( // Context functions to work with messages -pub(crate) async fn set_msg_failed(context: &Context, msg_id: MsgId, error: &str) -> Result<()> { - let mut msg = Message::load_from_db(context, msg_id).await?; - +pub(crate) async fn set_msg_failed( + context: &Context, + msg: &mut Message, + error: &str, +) -> Result<()> { if msg.state.can_fail() { msg.state = MessageState::OutFailed; - warn!(context, "{} failed: {}", msg_id, error); + warn!(context, "{} failed: {}", msg.id, error); } else { warn!( context, - "{} seems to have failed ({}), but state is {}", msg_id, error, msg.state + "{} seems to have failed ({}), but state is {}", msg.id, error, msg.state ) } + msg.error = Some(error.to_string()); context .sql .execute( "UPDATE msgs SET state=?, error=? WHERE id=?;", - (msg.state, error, msg_id), + (msg.state, error, msg.id), ) .await?; context.emit_event(EventType::MsgFailed { chat_id: msg.chat_id, - msg_id, + msg_id: msg.id, }); Ok(()) @@ -2300,7 +2303,7 @@ mod tests { update_msg_state(&alice, alice_msg.id, MessageState::OutMdnRcvd).await?; assert_state(&alice, alice_msg.id, MessageState::OutMdnRcvd).await; - set_msg_failed(&alice, alice_msg.id, "badly failed").await?; + set_msg_failed(&alice, &mut alice_msg, "badly failed").await?; assert_state(&alice, alice_msg.id, MessageState::OutFailed).await; // check incoming message states on receiver side diff --git a/src/mimeparser.rs b/src/mimeparser.rs index 1a5ecbe1e..73952ba8b 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -29,7 +29,9 @@ use crate::events::EventType; use crate::headerdef::{HeaderDef, HeaderDefMap}; use crate::key::{DcKey, Fingerprint, SignedPublicKey, SignedSecretKey}; use crate::keyring::Keyring; -use crate::message::{self, set_msg_failed, update_msg_state, MessageState, MsgId, Viewtype}; +use crate::message::{ + self, set_msg_failed, update_msg_state, Message, MessageState, MsgId, Viewtype, +}; use crate::param::{Param, Params}; use crate::peerstate::Peerstate; use crate::simplify::{simplify, SimplifiedText}; @@ -2156,7 +2158,8 @@ async fn handle_ndn( let mut first = true; for msg in msgs { let (msg_id, chat_id, chat_type) = msg?; - set_msg_failed(context, msg_id, &error).await?; + let mut message = Message::load_from_db(context, msg_id).await?; + set_msg_failed(context, &mut message, &error).await?; if first { // Add only one info msg for all failed messages ndn_maybe_add_info_msg(context, failed, chat_id, chat_type).await?; diff --git a/src/smtp.rs b/src/smtp.rs index ba371da44..e9ebf3faa 100644 --- a/src/smtp.rs +++ b/src/smtp.rs @@ -492,8 +492,19 @@ pub(crate) async fn smtp_send( if let SendResult::Failure(err) = &status { // We couldn't send the message, so mark it as failed - if let Err(err) = message::set_msg_failed(context, msg_id, &err.to_string()).await { - error!(context, "Failed to mark {msg_id} as failed: {err:#}."); + match Message::load_from_db(context, msg_id).await { + Ok(mut msg) => { + if let Err(err) = message::set_msg_failed(context, &mut msg, &err.to_string()).await + { + error!(context, "Failed to mark {msg_id} as failed: {err:#}."); + } + } + Err(err) => { + error!( + context, + "Failed to load {msg_id} to mark it as failed: {err:#}." + ); + } } } status @@ -541,7 +552,8 @@ pub(crate) async fn send_msg_to_smtp( ) .await?; if retries > 6 { - message::set_msg_failed(context, msg_id, "Number of retries exceeded the limit.").await?; + let mut msg = Message::load_from_db(context, msg_id).await?; + message::set_msg_failed(context, &mut msg, "Number of retries exceeded the limit.").await?; context .sql .execute("DELETE FROM smtp WHERE id=?", (rowid,))