I came up with an improved means of handling my own exception classes. Er, well, improved for me anyway. More capable programmers than I probably do even more interesting stuff.
My initial use of exception classes basically consisted of the following:
class myError(Exception):
def __init__(self, msg):
self.message = msg
def __str__(self)
return self.message
When I wanted to create an exception, I’d raise it like so:
if an_exception_should_be_raised:
raise myError("Error string")
The error string would be something useful to identify what the problem was. In turn, I would capture them in the usual try: ... except:
statements and just print out the error and exit the program.
In the course of modifying my program, I came across a situation where, to implement an improvement, I needed to detect a certain kind of error within the exception class. For that specific case, the program would behave a little differently, while for all other cases, I wanted the program to do the usual abort with a message.
In thinking over how to approach it, I realized something about the except
clauses I was using. The exception returns an instance of the error object:
try:
... some code ...
except myError, err:
... exception handling ...
The err
is an instance of my exception class myError
. I then realized that I could create an error code that would allow me to differentiate the type of exception being raised. So after a little experimentation and refinement, my new exception class looks like this:
class myError(Exception):
ERRCODE1 = 0
ERRCODE2 = 1
ERRCODE3 = 3
ERR_STRINGS = [
'Error string 1',
'Error string 2',
'Error string 3'
]
def __init__(self, err_code):
self.message = "myError: %s\n" % self.ERR_STRINGS[err_code]
self.code = err_code
def __str__(self):
return self.message
So now, I raise an exception like so:
if an_exception_should_be_raise:
raise myError(myError.ERRCODE1)
and I can now determine the specific exception with an if
statement under the except
:
try:
...some code...
except myError, err:
if err.code == myError.ERRCODE1:
... other code ...
else:
... print and exit ...
I gained several advantages with the new exception class. First, the error strings are now all kept with the exception class, so I don’t have to continually duplicate the string throughout my code every time I raise the same exception. Second, I achieved my objective where I can detect a certain type of error condition within my exception class so I can handle it a little differently. For me, this is superior to creating different exception classes and coding to catch all the different ones. I prefer a general class for my module so I only have to worry about catching one kind of exception. Third, the error code gives me a more terse means of coding what happened, so my code where the error is created has become more readable without long strings being passed to the exception.