0
votes

I'm currently writing a script in Python 2.7 which iterates through emails in an outlook folder, retrieves The email senders and saves the emails to a folder on the local machine. There's a problem however when the email has been recalled by the sender, an error occurs and the script doesn't work. Here's the bit of code that causes an error:

    if message.Class == 43:
        if message.SenderEmailType == 'EX':
            Sender = message.Sender.GetExchangeUser().PrimarySmtpAddress
        else:
            Sender = message.SenderEmailAddress

and the error:

if message.SenderEmailType == 'EX': File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 516, in getattr ret = self.oleobj.Invoke(retEntry.dispid,0,invoke_type,1) pywintypes.com_error: (-2147467262, 'No such interface supported', None, None)

the question is, how do i handle such objects where the email has been recalled by the sender? I have to either skip them or move them to a different folder but message.Move doesnt work either on recalled emails (same error, no such interface supported).

whole code:

import os
import win32com.client
import itertools
import shutil


OlSaveAsType = {
    "olTXT": 0,
    "olRTF": 1,
    "olTemplate": 2,
    "olMSG": 3,
    "olDoc": 4,
    "olHTML": 5,
    "olVCard": 6,
    "olVCal": 7,
    "olICal": 8
}

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
folder = outlook.Folders("MyFolder")
inbox = folder.Folders("Inbox")
Checked = inbox.Folders("Checked")
Sent = inbox.Folders("Sent")


messages = Checked.Items
a = (len(messages))
message = messages.GetFirst()
id = 1


for _ in itertools.repeat(None, a):

    messages = Checked.Items
    message = messages.GetFirst()
    Subject = message.subject

    if message.Class == 43:
        if message.SenderEmailType == 'EX':
            Sender = message.Sender.GetExchangeUser().PrimarySmtpAddress
        else:
            Sender = message.SenderEmailAddress

    message.SaveAs(newpath + '\\' + Sender + " " + str(id) + ".msg", OlSaveAsType['olMSG'])
    id = int(id)
    id += 1
    message.Move(Sent)
    if id == 600:
        break
    message = messages.GetNext()
1

1 Answers

0
votes

As easy way to get pass that is catch the error and except that particular. I saw someone who was explicitly catching which error code specifically using e.excepinfo[index of error value] but i could not get that to work which would be better but as a catch all for all com_errors.

from pywintypes import com_error
try:
    for item in inboxMsgs:
        print(item)
except com_error:
    print('Bad Email Skipped . . .')
    input('press enter to continue. . . ')

I ran into the same issue and was fine with just ignoring bad messages in my inbox.