blanket except clause -- best practice?

Skip Montanaro skip at pobox.com
Tue Oct 28 12:49:30 EST 2003


    George> class DatabaseError(StandardError): pass
    George> class OperationalError(StandardError): pass

    George> try:
    George>     stuff
    George> except _pg.error, msg:
    George>     raise DatabaseError, "error '%s' in '%s'" % ( msg, sql )
    George> except:
    George>         raise OperationalError, "internal error in '%s'" % sql

    George> This accomplishes passing useful info, namely "sql", on with the
    George> exception.  Unfortunately it *loses* info in that upstream has
    George> no way to know *which* exception triggered this or what args it
    George> might have been given.  I'm trying to think of a clean way to
    George> improve this.  I could do:

    George> try:
    George>     stuff
    George> except _pg.error, msg:
    George>     raise DatabaseError, "error '%s' in '%s'" % ( msg, sql )
    George> except Exception, x:
    George>     raise OperationalError, "internal %s(%s) error in '%s'" (x.__class__, x.args, sql)

Perhaps you should simply reraise the original exception:

    try:
        stuff
    except _pg.error, msg:
        raise DatabaseError, "error '%s' in '%s'" % ( msg, sql )
    except:
        raise

The resulting traceback displayed may be lower level than you would like,
but at least no information about where the actual error occurred is lost.

You can also synthesize a new exception using the original stack frame:

    try:
        stuff
    except _pg.error, msg:
        raise DatabaseError, "error '%s' in '%s'" % ( msg, sql )
    except Exception, x:
        raise OperationalError, \
              "internal %s(%s) error in '%s'" (x.__class__, x.args, sql), \
              sys.exc_info()[2]

This uses the original traceback object (sys.exc_info()[2]), but raises it
with your OperationalError and error string, which can obviously include
object values not available at the actual point where the original exception
was raised.  You could obviously include the first two values from
sys.exc_info() in your new exception as well.

Skip





More information about the Python-list mailing list