[Tutor] I need to ignore an error let the script continue to run

Peter Otten __peter__ at web.de
Wed May 6 05:28:13 EDT 2020


Jim wrote:

> On 5/5/20 4:13 PM, Mark Lawrence wrote:
>> On 05/05/2020 21:28, Jim wrote:
>>> On 5/5/20 9:38 AM, Jim wrote:
>>>> On 5/5/20 3:01 AM, Alan Gauld via Tutor wrote:
>>>>> On 05/05/2020 03:41, Jim wrote:
>>>>>
>>>>>> It seems try/except will not process the keys after the missing one.
>>>>>
>>>>> You need to wrap each bit that needs to continue in try/except.
>>>>> Clunky I agree.
>>>>>
>>>>>> 'Recepient username: ' + header['to'].addresses[0].username+'\n',
>>>>>> 'Sender name: ' + header['from'].addresses[0].display_name
>>>>>>
>>>>>> They don't look like keys, but they do resolve to the info I want
>>>>>> if it
>>>>>> is in the header.
>>>>>
>>>>> They aren't keys they are accessing attributes of some class that is
>>>>> returned. You could check the return value from header first using
>>>>> an if
>>>>> test. Or you could just wrap those two calls in their own try/except.
>>>>>
>>>>> Or you could use get() and return a dummy instance of whatever class
>>>>> it is with whatever default values you need.
>>>>>
>>>>> So several solutions only you can decide which suits you best.
>>>>
>>>> OK, thanks, I'll give them a try and see which on works best.
>>>>
>>>
>>> It seems every time I tried to test the return value from header I
>>> would get an error, so I went the try/except route. This what I ended
>>> up with:
>>>
>>> def parse_header(msg):
>>> with open('/home/jfb/' + email_msg, 'rb') as fp:
>>> header = BytesHeaderParser(policy=default).parse(fp)
>>> #  Now the header items can be accessed as a dictionary:
>>> try:
>>> username =  header['to'].addresses[0].username + '\n'
>>> except:
>> 
>> Never use a bare except as in the long term it's asking for trouble,
>> catch what you know can occur and let anything else raise it's own
>> exception.
>> 
>>> username = ' Blank \n'
> 
> I just write small scripts for my own use, so I really haven't had the
> occasion to use try/except much. I'm sure your advice it correct in most
> cases. I'm using try/except more like an 'if'. I needed some way to test
> if certain items were  not in the header data being returned. It seemed
> that no matter how I tried to reference them I got an error because they
> tried to return data that was not there. Maybe it can be done but I
> could never figure it out. Alan suggested a couple of things, one of
> which was try/except. That's how I came up with what you see. I'm
> probably abusing try/except, but it works and if it breaks I'll just
> have to fix it.
> 
> Thanks for your input.

> I just write small scripts for my own use

I sometimes use that as an excuse to do nasty things, too, but with broad 
excepts you tend to make your life harder than need be.

And it's really easy to be specific. If you run your script and get an 
exception in the line

username = header['to'].addresses[0].username + '\n'

the traceback will tell you what exception to catch, or what problem to 
guard against. For instance:

[...]
    username =  header['to'].addresses[0].username + '\n'
AttributeError: 'NoneType' object has no attribute 'addresses'

You could catch the AttributeError, but the error message tells you that 
header["to"] is None, so you probably don't use try...except at all:

header_to = header["to"]
if header_to is None:
    username = "#missing"
else:
    username = header_to.adresses[0].username + "\n"

The code runs for a while, and then you get

    username = header_to.addresses[0].username + "\n"
IndexError: list index out of range

Again you could catch

try:
    address = header_to.addresses[0]
except IndexError:
    ...
else
   username = address.username + "\n"

or add an explicit check:

addresses = header_to.addresses
if len(addresses) > 0:  # the idiomatic check would be 'if addresses: ...'
    username = addresses[0].username
else:
    ...

In short: you run(*) your script, see a specific exception, and write code 
to handle just that exception, either by catching it or by adding a check to 
avoid it. 

A bare except will sabotage this iterative process and you won't see other 
problems at the line where they originate, making them much harder to debug.

(*) The "professional" version of "run your script" is of course to write 
unit tests and run those.



More information about the Tutor mailing list