Python and custom Exception classes – Namespaces required
Having just spent the last three days fighting with python and it’s handling of custom exceptions, I thought I’d document the problem here for other people who trip over the same problem. Call it document-as-you-fail learning. In hindsight, it’s kind of obvious what’s happened, but it’s just slightly frustrating in the meantime.
Let’s say you’re writing a project called Ripley. In the process of writing this, you spin the reusable code into a nice library, which you then import into your CLI or GUI program like so;
#!/usr/bin/python import ripley
Everything works great. Then one day you decide you need some exception code for an internal error. You rock on over to the docs.python.org website, and copy in their example code. Maybe you having something like this in your ripley.py library.
class RipleyError(Exception): def __init__(self, ivalue): Exception.__init__( self, ivalue ) self.value = ivalue print "RipleyError Raised!" def __str__(self): return self.value
This is supposed to be called with something like this;
class session:
def go():
raise RipleyError("I'm testing out my error class.")
In your main program in a file called cli.py you have something like this;
print "Starting." session = ripley.session(server) try: session.go(); except RipleyError, ex: print "A RipleyError was raised %s" % ex except: print "Failed with non-specific error" else: print "No error raised." finally: print "Last thing." sys.exit()
*Deep breath*
You run the program, and the following happens;
edward@entropy:~/working/libmedusa-python$ python ./cli.py Starting RipleyError Raised! Last thing.
Hang on, the error has been raised, but it’s not being located when you call except on it?
As it turned out, the problem lay in the name space of the two files. The ‘fix’ is to attach the appropriate namespace to the Exception class, like so;
try: session.go(); except ripley.RipleyError, ex: print "A RipleyError was raised %s" % ex
The problem is that python appears not to be too perturbed that it’s being asked to check for an Exception class that does not in fact, exist.
Update: My preview is horribly horribly broken.
I think the issue here is that the first part of the except clause of a try statement takes a type, and that type could be created on the fly by the code inside the try – therefore, it can’t be checked at compile time. In fact if you read the docs, inspecting the except clause for exception handlers has to happen at run time:
“When an exception occurs in the try suite, a search for an exception
handler is started. This search inspects the except clauses in turn
until one is found that matches the exception.”