18

So I want to know which is the right way to write try except statements. I'm new to error handling in Python.

Option 1

try:
    itemCode = items["itemCode"]
    dbObject=db.GqlQuery("SELECT * FROM %s WHERE code=:1" % dbName,itemCode).get()
    dbObject.delete() 
except AttributeError:
    print "There's no item with that code"
except KeyError:
    print "Bad parameter name"
except:
    print "Unknow error" 

Option 2

try:
    itemCode = items["itemCode"]
except KeyError:
    print "Bad parameter name"
else:    
    dbObject=db.GqlQuery("SELECT * FROM %s WHERE code=:1" % dbName,itemCode).get()
    try:    
        dbObject.delete() 
    except AttributeError:
        print "There's no item with that code"
    except:
        print "Unknow error" 

Option 3 Any other better option you can think of.

Option 1, we see that I wrap all the code in a try block. Option 2, it uses nested blocks. It raises an exception on specific line statements.

If there's an error somewhere I will be glad to know about it.

6
  • I don't fully understand your question. It seems to me that your primary problem is with understanding how try, except, else, finally works. Is that correct? If so, I can provide an example that explains this. Commented Nov 17, 2012 at 18:55
  • @inspectorG4dget - I think the question is less about how they work (both examples are valid) and a stylistic preference question. Commented Nov 17, 2012 at 18:56
  • I don't understand why you are deleting the object in the try: block and the else: block, am I missing something or does this not make sense? Commented Nov 17, 2012 at 18:58
  • 2
    you probably should use if dbObject is not None: dbObject.delete() instead of catching AttributeError here. Commented Nov 17, 2012 at 19:13
  • @inspectorG4dget Lattyware It's about coding style. It doesn't matter what the code does. J.F. Sebastian. I think that's another subject, about using if vs try statements Commented Nov 17, 2012 at 19:26

3 Answers 3

5

From the zen of python, "flat is better than nested." I'd go with Option #1 style in general, though I'm a bit confused as to whether dbObject=db.GqlQuery("SELECT.... or dbObject.delete() raises an AttributeError. In any case though, you shouldn't have to call the dbObject.delete() more than once.

Sign up to request clarification or add additional context in comments.

8 Comments

my bad, i fixed the double deleting. dbObject.delete() raises the AttributeError
It's not good idea to catch all errors and hide them by simple "unknown error" message. It's hard to understand, what happened, when you see such error message.
@cleg it's for errors i don't know about. When they come i will catch them
@john.dou.2011 The idea of exception handling is that if you don't know about the error and how to handle it, you let it propogate to something that might be able to and although you're printing "Unknow error" I think cleg is pointing out that it's easy to miss and consequently strange things could happen...
@jonClements Sorry, i don't quite understand your concept. Maybe you could show me by an coding example or point me to the right direction for further reading. Thanks
|
0

Simple - it depends. If you are certain about what exceptions you're going to get, you can stick with 1) and frankly, it is the case 90% of the time. The second way is useful if you know that many code routines can raise the same exception type.

Comments

-1

Instead of catching KeyError, I prefer using get method of dicts with validation.

itemCode = items.get("itemCode") # itemCode will be None, if no such key
if itemCode is not None:
    print "code missing"

This is not "general" solution (see comments to my answer), but in this case it'll help.

And in first case I don't understand, why you trying to delete two times.

try:
    itemCode = items.get("itemCode") # itemCode will be None, if no such key
    if itemCode is not None:
        print "code missing"
    dbObject=db.GqlQuery("SELECT * FROM %s WHERE code=:1" % dbName,itemCode).get()
    dbObject.delete() 
except AttributeError:
    print "There's no item with that code"
except StandardError as ex:    # good idea to be prepared to handle various fails
    print "Unexpected error deleting item {}".format(ex)

And also, don't forget that python have finally section. It's oftem comes in handy sometimes.

4 Comments

That's not a very Pythonic approach, for the reason that your code fails where items['itemCode'] is 0, False, [], {}, or anything else that evaluates to False. try/except is much preferred in this situation because it actually catches the specific case where the item wasn't found. There aren't the false positives that if not itemCode can incur.
Yes, I'm really sorry, it's my mistake (really tired and tried to answer quickly). Sure, is None and is not None should be used always for checking if value is None (or isn't). I've corrected code.
No apologies. We're all here trying to work through this stuff together. :-) But even in the new code, you can't tell the difference between 'itemCode' not in items and items['itemcode'] is None. None is a perfectly valid value to store, and there's a big difference between None and KeyError.
Yep, you right. The best way is to check subkeys, using in. I still think it's better in most cases then cathing exceptions. But in many cases (and this one also) — None is non-acceptable value, so this will work. But definitely, you need to understand the risk of doing so.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.