Different Python User Exception Handling

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.

Leave a Reply

Your email address will not be published. Required fields are marked *