From 19b1db590927d0180846609ca597681ef240de6d Mon Sep 17 00:00:00 2001 From: Simon Chopin Date: Mon, 20 Apr 2026 16:50:57 +0200 Subject: [PATCH] compose: kill the sendmail process on timeout When you write an email and your sendmail process times out, the thread finishes, but the underlying process is still kicking around. This results in duplicate emails being sent, as the user (randomly, me) will try again. In my case, it happens because I use `gmi` for both syncing and sending email, and the send subcommand actually blocks if a sync is in progress, and sometimes those can be pretty long if you have a lot of tag changes (Google is pretty swift in rate-limiting). I also patched that tool to fail rather than block, but I figure that Dodo should also do the right thing here. Further work would be to also think about that process when the main one exits, but that's out of scope for this patch. --- dodo/compose.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dodo/compose.py b/dodo/compose.py index bbb8b36..48f1403 100644 --- a/dodo/compose.py +++ b/dodo/compose.py @@ -439,7 +439,12 @@ def run(self) -> None: if sendmail.stdin: sendmail.stdin.write(eml.as_string()) sendmail.stdin.close() - sendmail.wait(30) + try: + sendmail.wait(timeout=30) + except TimeoutExpired: + sendmail.terminate() + self.panel.set_status("timed out", color="fg_bad") + return if sendmail.returncode == 0: # save to sent folder if isinstance(settings.sent_dir, dict): @@ -465,8 +470,6 @@ def run(self) -> None: self.panel.set_status("sent", color="fg_good") else: self.panel.set_status("error", color="fg_bad") - except TimeoutExpired: - self.panel.set_status("timed out", color="fg_bad") except pgp_util.GpgError as e: self.panel.set_status(f"GPG error: {e}", color="fg_bad") except Exception as e: