Python Forum
Use try to get over problems?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Use try to get over problems?
#1
I have a little routine to download email and save the text body, the students' answers, to my computer. It does what I want. However, for some reason, I not sure why, something weird in the email format, or the student has recalled it, it breaks down. I can see which email and which student number caused the problem on my screen. I delete that email by hand in my email client.

Then I have to start again. Download 100 emails again, takes a while.

How can I make the program carry on?

Is that what 'try' is for?
Reply
#2
Quote:Is that what 'try' is for?
Simple answer No, but you might be able to use it if you write the code properly

Try/Except are used in pairs.
you try to run the code that falls between the two commands, if there is an exception and your except clause is set up to catch the exception, it will execute the code in the except clause.
Example:
thedict = {
    "Harry": "Harry lives here",
    "Jack": "Jack lives here"
}

try:
    print(thedict['Harry'])
except KeyError:
    print('Harry is not an option')

try:
    print(thedict['Mary'])
except KeyError:
    print('Mary is not an option')

# You can have as much code as needed in the try clause, if any part of that code fails,
try:
    print()
    print(thedict['Harry'])
    print(thedict['Mary'])
except keyError:
    print('Something failed')
results:
Output:
Harry lives here Mary is not an option Harry lives here Something failed
When you try to print mary it creates the exception in both cases
Reply
#3
(Oct-21-2018, 11:12 PM)Pedroski55 Wrote: How can I make the program carry on?

Is that what 'try' is for?
You can catch the error and make it continue with pass.
>>> lst = [1, 4, 7, 9, 10, 20, 100]
>>> for n in lst:
...     print(f'{2 / n:.2f}')
...     
2.00
0.50
0.29
0.22
0.20
0.10
0.02
>>> 
>>> lst = [1, 4, 7, 9, 10, 0, 20, 100]
>>> for n in lst:
...     print(f'{2 / n:.2f}')
...     
2.00
0.50
0.29
0.22
0.20
Traceback (most recent call last):
  File "<string>", line 449, in runcode
  File "<interactive input>", line 2, in <module>
ZeroDivisionError: division by zero
So when it's a error in list 0 it stop and two last values 20, 100 do not get executed.
>>> lst = [1, 4, 7, 9, 10, 0, 20, 100]
>>> for n in lst:
...     try:
...         print(f'{2 / n:.2f}')
...     except ZeroDivisionError:    
...          pass
...      
2.00
0.50
0.29
0.22
0.20
0.10
0.02
Now it skip error and run last 2 values.
The problem now can be that do not know what happens,to fix this can logg it.
import my_log

lst = [1, 4, 7, 9, 10, 0, 20, 100]
for n in lst:
    try:
        my_log.logger.debug(n)
        print(f'{2 / n:.2f}')
    except ZeroDivisionError:
        my_log.logger.exception('msg')
        pass
logg.log:
Output:
2018-10-22 05:11:04,491 - my_log - DEBUG - 1 2018-10-22 05:11:04,491 - my_log - DEBUG - 4 2018-10-22 05:11:04,491 - my_log - DEBUG - 7 2018-10-22 05:11:04,492 - my_log - DEBUG - 9 2018-10-22 05:11:04,492 - my_log - DEBUG - 10 2018-10-22 05:11:04,492 - my_log - DEBUG - 0 2018-10-22 05:11:04,492 - my_log - ERROR - msg Traceback (most recent call last): File "E:\div_code\new\pass_on.py", line 7, in <module> print(f'{2 / n:.2f}') ZeroDivisionError: division by zero 2018-10-22 05:11:04,493 - my_log - DEBUG - 20 2018-10-22 05:11:04,493 - my_log - DEBUG - 100
Boilerplate my_log:
Reply
#4
So can exception somehow make my little routine carry on? The thing is, I don't mark any emails as SEEN until I have successfully downloaded the majority, except of course for the 'exceptions'.

I can't give an example of a breakdown now, but I will save it next time and get back to this thread.
Reply
#5
You should post your code together with the stacktrace.
Otherwise it's guessing.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#6
Here is the code that does the work of getting and saving the emails:

pathToFiles = '/home/pedro/getEmailtexts/emailTexts17BE/'
server = IMAPClient(HOST, use_uid=True, ssl=True)
server.login(USERNAME, PASSWORD)
select_info = server.select_folder('Inbox')
unseenMessages = server.search(['UNSEEN'])
print('Number of unseen messages is ' + str(len(unseenMessages)))

for uid, message_data in server.fetch(unseenMessages, 'RFC822').items():
        email_message = email.message_from_bytes(message_data[b'RFC822'])
        print(' message UID is ' + str(uid))
        print(email_message.get('Subject'))
        messageSubject = email_message.get('Subject')
        file = messageSubject + '.txt'
        theFile = open(pathToFiles + file, 'w')
        rawMessage = server.fetch(unseenMessages, ['BODY[]', 'FLAGS'])
        message = pyzmail.PyzMessage.factory(rawMessage[uid][b'BODY[]'])
        text = message.text_part.get_payload().decode(message.text_part.charset)
        saveText = text.rstrip()
        theFile.write(saveText)
        theFile.close()
and this, for example was the error I got. After I deleted this and 1 other email, the rest downloaded no problems. First I got about 20 emails which did not cause problems, then UID 33, 34. UID 35 was the problem.

Quote:1725010108week8
message UID is 33
1725010135week8
message UID is 34
1725010126 week8
message UID is 35
������������������1725010118week8
Traceback (most recent call last):
File "./getAnswersFromEmail17BEv2.py", line 45, in <module>
file = messageSubject + '.txt'
TypeError: unsupported operand type(s) for +: 'Header' and 'str'
pedro@pedro-newssd:~/getEmailtexts/python$

How might I make the program ignore this kind of mistake and go to the next UID?
Reply
#7
Can do as i have showed you,but you pass out TypeError.
Or you can look at email_message.get('Subject') and try to clean it up before doing messageSubject + '.txt' .
PEP-8 Wink
Reply
#8
Well, this seems to fix the problems. 1) Weird entry in the subject field. 2) Empty email. I downloaded 90+ emails last night without a hitch.

for uid, message_data in server.fetch(unseenMessages, 'RFC822').items():
        email_message = email.message_from_bytes(message_data[b'RFC822'])
        print('UID is ' + str(uid))
        print(email_message.get('Subject'))
        messageSubject = str(email_message.get('Subject'))
        print('Message subject is ' + messageSubject)
        if messageSubject == None:
            messageSubject = 'idiot'
        file = messageSubject + '.txt'
        theFile = open(pathToFiles + file, 'w')
        rawMessage = server.fetch(unseenMessages, ['BODY[]', 'FLAGS'])
        try:
            message = pyzmail.PyzMessage.factory(rawMessage[uid][b'BODY[]'])
            text = message.text_part.get_payload().decode(message.text_part.charset)
            saveText = text.rstrip()
            theFile.write(saveText)
            theFile.close()
        except AttributeError:
            continue
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020