diff --git a/lib/Service/MailTransmission.php b/lib/Service/MailTransmission.php index be808fc6fb..89e0f15771 100644 --- a/lib/Service/MailTransmission.php +++ b/lib/Service/MailTransmission.php @@ -14,6 +14,7 @@ use Horde_Imap_Client_Data_Fetch; use Horde_Imap_Client_Fetch_Query; use Horde_Imap_Client_Ids; +use Horde_Mail_Exception; use Horde_Mail_Rfc822_Address; use Horde_Mail_Rfc822_List; use Horde_Mail_Transport_Null; @@ -51,6 +52,7 @@ use OCP\AppFramework\Db\DoesNotExistException; use OCP\EventDispatcher\IEventDispatcher; use Psr\Log\LoggerInterface; +use Throwable; class MailTransmission implements IMailTransmission { private const RETRIABLE_CODES = [ @@ -155,7 +157,7 @@ public function sendMessage(Account $account, LocalMessage $localMessage): void // Send the message try { $mail->send($transport, false, false); - $localMessage->setRaw($mail->getRaw(false)); + $localMessage->setRaw($this->getRawAsString($mail)); $localMessage->setStatus(LocalMessage::STATUS_RAW); } catch (Horde_Mime_Exception $e) { if ($e->getPrevious() instanceof Horde_Smtp_Exception) { @@ -172,13 +174,19 @@ public function sendMessage(Account $account, LocalMessage $localMessage): void $localMessage->setStatus(LocalMessage::STATUS_SMPT_SEND_FAIL); return; } + + try { + $localMessage->setRaw($this->getRawAsString($mail)); + } catch (Throwable) { + // Having the raw message is nice for troubleshooting, but should not fail hard. + } $localMessage->setStatus(LocalMessage::STATUS_ERROR); return; } finally { if ($transport instanceof Horde_Mail_Transport_Smtphorde) { try { $transport->getSMTPObject()->logout(); - } catch (\Throwable $e) { + } catch (Throwable) { // Handle silently as this is a resource usage optimization } } @@ -233,7 +241,7 @@ public function saveLocalDraft(Account $account, LocalMessage $message): void { $this->messageMapper->save( $client, $draftsMailbox, - $mail->getRaw(false), + $this->getRawAsString($mail), [Horde_Imap_Client::FLAG_DRAFT] ); $perfLogger->step('save local draft message on IMAP'); @@ -319,7 +327,7 @@ public function saveDraft(NewMessageData $message, ?Message $previousDraft = nul $newUid = $this->messageMapper->save( $client, $draftsMailbox, - $mail->getRaw(false), + $this->getRawAsString($mail), [Horde_Imap_Client::FLAG_DRAFT] ); $perfLogger->step('save message on IMAP'); @@ -437,4 +445,20 @@ public function sendMdn(Account $account, Mailbox $mailbox, Message $message): v } } + /** + * @throws Horde_Mail_Exception if no base part set + */ + public function getRawAsString(Horde_Mime_Mail $mail): string { + $raw = $mail->getRaw(false); + if (is_resource($raw)) { + // dead code to make psalm happy + // https://github.com/bytestream/Mime/pull/15 + $raw = stream_get_contents($raw); + if ($raw === false) { + return ''; + } + } + return $raw; + } + }