Can anyone give me advice for this issue? I am not getting any error messages and don't know where to start.
I made a program that checks emails in an Outlook inbox for pdf attachments from a list of senders, then saves the attachments to a folder. You put in a starting date and choose how many days you want to search through. There is a line in the code to show all emails being checked even if they aren't related to the sender/s for debugging. It has been working fine for months, until recently I got an email from ebay that contains an emote of a packed cardboard box in the subject line, and this specific email causes the program to misbehave.
Here's an example of the erroneous output - I've put in zero to search for 'any sender' from a list, and chosen a date range like always. The first Attribute Error is caused by an undeliverable message (which is not considered class 43 'mail' by outlook). You can see that the first normal mail item in the date range gets checked, with the subject line etc displayed, but then the next message is the ebay email, which is way outside the date range. The program skips over several days without checking any other emails in that range and ends the search. Same thing happens if I disable the display of every email in output (all emails still get read by the program, but there is a line to display only relevant ones).
There seems to be some issue with that specific email - Ebay is not one of the senders in the list the program checks for attachments, and even if I have a date range of zero days it will still show that email from a week ago as the last email checked. The only thing that seems unique about it is the cardboard box emote in the subject line, there is nothing else about it that stands out to me.
Here is the output:
Choose a sender (blank to exit): 0
Enter a starting search date in format dd-mm-yyyy (blank to exit): 05-05-2020
Enter how many days previous to search through: 3
Your search starts from 2020-05-05 00:00:00 and ends on 2020-05-02
Searching for any sender
Searching...
Attribute error (not class 43 mail) for item at mainChoice0() - .MessageClass REPORT.IPM.Note.NDR - Class 46
Looking at [...], WordPress has been updated on [...]. 2020-05-05
Looking at ???? ORDER DELIVERED: 10x Capacitive Stylus Pen Tou… 2020-04-28
Reached end of date range: final message - ???? ORDER DELIVERED: 10x Capacitive Stylus Pen Tou… 2020-04-28
If I move the problematic email to a different inbox then my program will correctly check emails across the whole date range I entered.
It gets weirder, because if put in a date range that would include that particular ebay email, then it DOES NOT appear in the output, while OTHER ebay emails which include emotes like a truck or a ticked box DO get checked by the program.
Looking at ???? ORDER UPDATE: 10x Capacitive Stylu... 2020-04-22
Looking at FAILED Schemus mail synchronization 2020-04-22
Attribute error (not class 43 mail) for item at mainChoice0() - .MessageClass REPORT.IPM.Note.NDR - Class 46
Attribute error (not class 43 mail) for item at mainChoice0() - .MessageClass REPORT.IPM.Note.NDR - Class 46
Looking at Active Directory Sync Failure 2020-04-21
Looking at ✅ ORDER CONFIRMED: 10x Capacitive Stylu... 2020-04-21
Below is the block of code for collecting attachments:
def mainChoice0(): #COLLECT ATTACHMENTS
#Choose sender from menu.
senderNum = input("Choose a sender (blank to exit): ")
if senderNum == "":
mainChoiceDisplay0 = False
topMenu() #Return to main menu
else:
senderNum = int(senderNum)
senderChoice = listSender[senderNum]
####Determine search range by date
startDate = input("Enter a starting search date in format dd-mm-yyyy (blank to exit): ")
if startDate == "":
mainChoiceDisplay0 = False
topMenu()
#strptime will convert startDate from a string to a usable date
startDate = datetime.datetime.strptime(startDate, "%d-%m-%Y")
searchRange = int(input("Enter how many days previous to search through: "))
searchDate = startDate.date() - datetime.timedelta(days = searchRange)
print("Your search starts from", startDate, "and ends on", searchDate, "\n")
#SEARCH ANY SENDERS
if senderNum == 0:
print("Searching for any sender")
print("Searching...")
#LOOK AT INBOX CONTENTS
for msg in reversed(itcontents): #reversed() looks at most recent received email first based on date
#while mainChoiceDisplay0 == True:
try:
###!!! uncomment this to see details about every email even if they aren't relevant to the search !!!####
print("Looking at", msg, msg.SentOn.date())
#msg.Sender is sender name, msg.SenderEmailAddress is the address.
if ( (str(msg.SenderEmailAddress) or str(msg.Subject) or str(msg.Sender) or str(msg.SentOnBehalfOfName)) in senderDict and (msg.SentOn.date() >= searchDate and msg.SentOn.date() <= startDate.date())):
check += 1
print(check, "messages from", msg.SenderEmailAddress, "on", msg.SentOn.date()) #show number of messages from relevant senders
for x in msg.Attachments:
if str(".pdf").casefold() in str(x): #casefold() checks upper or lower case combinations e.g PDF pdf Pdf
x.SaveAsFile("C:\\Users\\"+emailUser+"\\Desktop\\Invoices from Outlook\\" + str(msg.SentOn.date()) + str(msg.SenderEmailAddress) + x.FileName)
print("Saved attachment", x, "from", str(msg.Sender()), "on", str(msg.SentOn.date()))
#break
#Stop searching inbox earlier than searchDate
nextMail() #Look at the next most recent email, repeat until end of date range
#Final message to indicate end of search, with subject line and date of the final message.
if msg.SentOn.date() < searchDate:
print("Reached end of date range: final message -", msg, msg.SentOn.date(), "\n")
mainChoiceDisplay0 = False
topMenu()
except UnicodeEncodeError: #unsupported characters
print("Subject line could not be parsed", msg, msg.SentOn.date())
#continue
except OverflowError: #caused by invalid or very old date e.g 01-01-0000
print("Date calculation caused an overflow error, possibly because you entered a very old date e.g 01-01-0000 at mainChoice0()")
#break
except AttributeError: #The email was the wrong class for the attribute msg.Sender or you tried to use an attribute that doesn't work for that method
print("Attribute error (not class 43 mail) for item at mainChoice0() - .MessageClass", msg.MessageClass, '- Class', msg.Class)
pass
except ValueError:
print("Invalid input caused a value error in mainChoice0().")