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