[Tutor] Catching different exceptions [Databases/Exceptions]

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Tue, 12 Feb 2002 11:13:13 -0800 (PST)


On Tue, 12 Feb 2002 mikalzet@libero.it wrote:

> import pgdb

Ah, PostgreSQL.  Be careful that you may need to think about transactions
by using 'commit()' --- Python's database API says that database drivers
don't auto-commit for us, at least, not by default.

"""
commit()
Commit any pending transaction to the database. Note that if the database
supports an auto-commit feature, this must be initially off. An interface
method may be provided to turn it back on.
"""

    (http://www.python.org/topics/database/DatabaseAPI-2.0.html)

I didn't know about this before, and got very confused when all my INSERT
commands never did anything... *grin*



> I can try to catch some exceptions like this:
> 
> try:
> 	db = dbpg.connect(database = 'turni')
> except:
> 	os.system('createdb turni')
> 
> This last can fail for various reasons:
> 1) I am not authorized to create new databases, in this case I need an
> error message telling me to contact my postgres administrator so that he
> can create it for me;
> 2) I am not an authorized user of postgres at all, so I need a different
> error message;
> 3) postgres doesn't exist on my system.


Yes, when we do something like:

### pseudocode
try:
    ...
except:
    ...
###

This is commonly called a "catch-all" because it doesn't distinguish
between the different types of exceptional behavior we can run into.  Not
that this isn't bad --- it's just that we often want to be able to look at
the errors in more detail.



> How do I tell python how to distinguish between different types of
> exceptions ?
> 
> Is it something like:
> 
> try:
> 	foo
> except(fooerror1):
> 	foo1
> except(fooerror2):
> 	foo2
> except(fooerror3):
> 	try:
> 		foo4
> 	except(fooerror4):
> 		foowhatever

Yes, exactly!  There are several defined Exceptions that can occur when we
do database stuff.  Here are the database-specific exception classes:

    InterfaceError
    DatabaseError
    DataError
    OperationalError
    IntegrityError
    InternalError
    ProgrammingError
    NotSupportedError

We can control the granularity of what we're looking for by taking
advantage of the class structure.  There's a functional tree of the
classes in the Database API:

    http://www.python.org/topics/database/DatabaseAPI-2.0.html

near the beginning of the page.


When we want to check for subtle stuff, we can place those cases first
when we do the exception handling:

###
## pseudocode
try: ...
except IntegrityError, e:
    ...
###



But we just want to catch all the errors related to Databases, we can do
something like:

###
## pseudocode
try: ...
except DatabaseError, e: ...
###

and that should catch everything that deals with Database stuff.