From 33134d45296d18754648a3d7d895a25dc814f13d Mon Sep 17 00:00:00 2001 From: Trenton Holmes Date: Tue, 19 Apr 2022 08:32:34 -0700 Subject: [PATCH 1/5] In the event of an error when setting the mail account folder, attempt to list the account's folders to the log --- src/paperless_mail/mail.py | 14 ++++++ src/paperless_mail/tests/test_mail.py | 70 ++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/paperless_mail/mail.py b/src/paperless_mail/mail.py index 5df29e2b0..471d861e1 100644 --- a/src/paperless_mail/mail.py +++ b/src/paperless_mail/mail.py @@ -190,6 +190,20 @@ class MailAccountHandler(LoggingMixin): try: M.folder.set(rule.folder) except MailboxFolderSelectError: + + self.log( + "error", + f"Unable to access folder {rule.folder}, attempting folder listing", + ) + try: + for folder_info in M.folder.list(): + self.log("info", f"Located folder: {str(folder_info)}") + except Exception: + self.log( + "error", + "Exception during folder listing, unable to provide list folders", + ) + raise MailError( f"Rule {rule}: Folder {rule.folder} " f"does not exist in account {rule.account}", diff --git a/src/paperless_mail/tests/test_mail.py b/src/paperless_mail/tests/test_mail.py index 9335bcd75..a638fc894 100644 --- a/src/paperless_mail/tests/test_mail.py +++ b/src/paperless_mail/tests/test_mail.py @@ -15,6 +15,7 @@ from django.test import TestCase from documents.models import Correspondent from documents.tests.utils import DirectoriesMixin from imap_tools import EmailAddress +from imap_tools import FolderInfo from imap_tools import MailboxFolderSelectError from imap_tools import MailMessage from imap_tools import MailMessageFlags @@ -53,13 +54,12 @@ class BogusMailBox(ContextManager): def __init__(self): self.messages: List[MailMessage] = [] self.messages_spam: List[MailMessage] = [] + self.folder = BogusFolderManager() def login(self, username, password): if not (username == "admin" and password == "secret"): raise Exception() - folder = BogusFolderManager() - def fetch(self, criteria, mark_seen, charset=""): msg = self.messages @@ -621,6 +621,72 @@ class TestMail(DirectoriesMixin, TestCase): self.assertEqual(len(self.bogus_mailbox.messages), 2) self.assertEqual(len(self.bogus_mailbox.messages_spam), 1) + def test_error_folder_set(self): + """ + GIVEN: + - Mail rule with non-existent folder + THEN: + - Should call list to output all folders in the account + - Should not process any messages + """ + account = MailAccount.objects.create( + name="test2", + imap_server="", + username="admin", + password="secret", + ) + _ = MailRule.objects.create( + name="testrule", + account=account, + action=MailRule.AttachmentAction.MOVE, + action_parameter="spam", + filter_subject="Claim", + order=1, + folder="uuuhhhh", # Invalid folder name + ) + + self.bogus_mailbox.folder.list = mock.Mock( + return_value=[FolderInfo("SomeFoldername", "|", ())], + ) + + self.mail_account_handler.handle_mail_account(account) + + self.bogus_mailbox.folder.list.assert_called_once() + self.assertEqual(self.async_task.call_count, 0) + + def test_error_folder_set_error_listing(self): + """ + GIVEN: + - Mail rule with non-existent folder + - Mail account folder listing raises exception + THEN: + - Should not process any messages + """ + account = MailAccount.objects.create( + name="test2", + imap_server="", + username="admin", + password="secret", + ) + _ = MailRule.objects.create( + name="testrule", + account=account, + action=MailRule.AttachmentAction.MOVE, + action_parameter="spam", + filter_subject="Claim", + order=1, + folder="uuuhhhh", # Invalid folder name + ) + + self.bogus_mailbox.folder.list = mock.Mock( + side_effect=MailboxFolderSelectError(None, "uhm"), + ) + + self.mail_account_handler.handle_mail_account(account) + + self.bogus_mailbox.folder.list.assert_called_once() + self.assertEqual(self.async_task.call_count, 0) + @mock.patch("paperless_mail.mail.MailAccountHandler.get_correspondent") def test_error_skip_mail(self, m): def get_correspondent_fake(message, rule): From 5603834282295874706cb6c3ab540a56b8136d22 Mon Sep 17 00:00:00 2001 From: Trenton Holmes Date: Tue, 19 Apr 2022 09:03:08 -0700 Subject: [PATCH 2/5] Only output the folder names --- src/paperless_mail/mail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/paperless_mail/mail.py b/src/paperless_mail/mail.py index 471d861e1..c9edf3e5e 100644 --- a/src/paperless_mail/mail.py +++ b/src/paperless_mail/mail.py @@ -197,7 +197,7 @@ class MailAccountHandler(LoggingMixin): ) try: for folder_info in M.folder.list(): - self.log("info", f"Located folder: {str(folder_info)}") + self.log("info", f"Located folder: {folder_info.name}") except Exception: self.log( "error", From 06cfba8c7e61c23a5f86ff9316cef9d8004cb570 Mon Sep 17 00:00:00 2001 From: Trenton Holmes Date: Tue, 19 Apr 2022 09:05:30 -0700 Subject: [PATCH 3/5] Updates the documentation --- docs/usage_overview.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/usage_overview.rst b/docs/usage_overview.rst index e6bb8f31e..5020b783d 100644 --- a/docs/usage_overview.rst +++ b/docs/usage_overview.rst @@ -184,7 +184,9 @@ These are as follows: define how the sub-folders are separated. Common values include ".", "/" or "|", but this varies by the mail server. Unfortunately, this isn't a value we can determine automatically. Either check the documentation for your mail server, or check for - errors in the logs and try different folder separator values. + errors in the logs and try different folder separator values. If possible, + the log will contain a listing of account folders, in the event of an error when + trying to fetch mail from a certain folder. .. note:: From 57f32e5360bb1c84d5a4290615a4079c7e014d2a Mon Sep 17 00:00:00 2001 From: Trenton Holmes Date: Tue, 19 Apr 2022 13:37:30 -0700 Subject: [PATCH 4/5] Includes exception information during exception listing folders Co-authored-by: Florian --- src/paperless_mail/mail.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/paperless_mail/mail.py b/src/paperless_mail/mail.py index c9edf3e5e..8a9c1106c 100644 --- a/src/paperless_mail/mail.py +++ b/src/paperless_mail/mail.py @@ -198,10 +198,11 @@ class MailAccountHandler(LoggingMixin): try: for folder_info in M.folder.list(): self.log("info", f"Located folder: {folder_info.name}") - except Exception: + except Exception as e: self.log( "error", - "Exception during folder listing, unable to provide list folders", + "Exception during folder listing, unable to provide list folders: " + + str(e), ) raise MailError( From c274bbcddf116f3b723172756f3411c779353a21 Mon Sep 17 00:00:00 2001 From: Trenton Holmes Date: Tue, 19 Apr 2022 15:35:45 -0700 Subject: [PATCH 5/5] Tweaks documentation around mail fetching sub-folders --- docs/usage_overview.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/usage_overview.rst b/docs/usage_overview.rst index 5020b783d..ea1080177 100644 --- a/docs/usage_overview.rst +++ b/docs/usage_overview.rst @@ -182,11 +182,10 @@ These are as follows: When defining a mail rule with a folder, you may need to try different characters to define how the sub-folders are separated. Common values include ".", "/" or "|", but - this varies by the mail server. Unfortunately, this isn't a value we can determine - automatically. Either check the documentation for your mail server, or check for - errors in the logs and try different folder separator values. If possible, - the log will contain a listing of account folders, in the event of an error when - trying to fetch mail from a certain folder. + this varies by the mail server. Check the documentation for your mail server. In the + event of an error fetching mail from a certain folder, check the Paperless logs. When + a folder is not located, Paperless will attempt to list all folders found in the account + to the Paperless logs. .. note::