Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

leaveUnread() does not work if an exception happens during fetching #507

Open
freescout-help opened this issue Aug 2, 2024 · 3 comments

Comments

@freescout-help
Copy link

One user reported an issue freescout-help-desk/freescout#4159.
If an error occurs during fetching the email in the mailbox stays "read" even though leaveUnread() is set.

Here is the example of headers which can be used to reproduce the issue:

X-Mailer: CodeIgniter
Date: Thu, 1 Aug 2024 10:55:28 +0100
    Precedence: bulk
    Auto-Submitted: auto-replied
X-Priority: 1 (Highest)

We've found out that the following line marks an email as "read": https://github.com/Webklex/php-imap/blob/master/src/Query/Query.php#L246

if ($this->getFetchBody()) {
	$contents = $this->client->getConnection()->content($uids, "RFC822", $this->sequence)->validatedData();
}

So apparently somewhere in the code there should a place marking an email as "unread" if leaveUnread() is set.
Is it so? If yes, can someone help to find that place in order to try to find a solution.

@freescout-help
Copy link
Author

It looks like messages are marked as "unread" here: https://github.com/Webklex/php-imap/blob/master/src/Message.php#L300

@freescout-help
Copy link
Author

Here is the fix for Query->populate() function https://github.com/Webklex/php-imap/blob/master/src/Query/Query.php#L339C24-L339C32:

+       $exception = null;
        foreach ($raw_messages["headers"] as $uid => $header) {
            $content = $raw_messages["contents"][$uid] ?? "";
            $flag = $raw_messages["flags"][$uid] ?? [];
            $extensions = $raw_messages["extensions"][$uid] ?? [];

+	    try {
                 $message = $this->make($uid, $msglist, $header, $content, $flag);
+           } catch (\Exception $e) {
+                $exception = $e;
+                continue;
+           }
            foreach ($extensions as $key => $extension) {
                $message->getHeader()->set($key, $extension);
            }
            if ($message !== null) {
                $key = $this->getMessageKey($message_key, $msglist, $message);
                $messages->put("$key", $message);
            }
            $msglist++;
        }
		
+       if ($exception) {
+           throw $exception;
+       }

It's quite an important thing as if someone fetches only unread emails (like us) and an exception happens for some email in a bunch all other emails will stay marked as "unread" and will be unprocessed.

@freescout-help
Copy link
Author

And here is the fix allowing to leave emails unread even if "Allowed memory size exhausted" fatal error occurs:

freescout-help-desk/freescout@b9391d8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant