views:

113

answers:

2

I'm having some problems implementing an exception system in my program. I found somewhere the following piece of code that I am trying to use for my program:

class InvalidProgramStateException(Exception):
    def __init__(self, expr, msg):
        self.expr = expr
        self.msg = msg

I think msg must be a string message to be shown, but how do I fill the "expr" when I want to raise this exception? Do I have to write it by hand?

raise InvalidProgramStateException(what_here?, "there was an error")
+2  A: 

Check this site: Error tutorials Python

pipelinecache
+4  A: 

Your custom exceptions don't actually need to take parameters at all. If you haven't got any particular error message or state to encapsulate in the Exception, this will work just fine:

class MyException(Exception):
    pass

This would allow your program to catch cases of this exception by type:

try:
    raise MyException()
except MyException:
    print "Doing something with MyException"
except:
    print "Some other error occurred... handling it differently"

If you want the Exception to have some meaningful string representation, or have properties that would provide your application greater details on what went wrong, that's when you pass additional arguments to the constructor. The number, name and type of these arguments is not really pre-defined by Python... they can be anything. Just be sure to provide a custom __str__ or __unicode__ method so you can provide a meaningful text depiction:

class MyException(Exception):

    def __init__(self, msg):
        self.msg = msg

    def __str__(self):
        return "MyException with %s" % self.msg

In the case of the example you're quoting, the expr and msg parameters are specific to the fictional case of the example. A contrived scenario for how these might be used is:

def do_something(expr):
    if 'foo' in expr:
        raise InvalidProgramStateException(expr, "We don't allow foos here")
    return 5

user_input = 'foo bar'
try:
    do_something(user_input)
except InvalidProgramStateException, e:
    print "%s (using expression %s)" % (e.msg, e.expr)

Since it doesn't appear that your application requires it, just drop the parameters you don't require.

Jarret Hardie
You don't need to provide a new constructor or `__str__()`. By default arguments will be placed in self.args, and they will be printed by `__str__()`.
Bastien Léonard
Thanks Bastien... a nice addition. I'm too used to being pedantic about Exceptions and their representation in logs - I appreciate you bringing me back to earth.
Jarret Hardie
You dont even need to instantiate: `raise MyException`
THC4k
Fair enough THC4k :-) You are, of course, right. For some reason that gives me the willies, though. I may just be having flashbacks to Guido recommending in Python 1.5 that exception constructors be called explicitly, but implicit instantiation leaves me feeling incomplete. I have no objective reason for this, though, so I'm glad you brought it up.
Jarret Hardie
@Jarret, I feel the same about it, and knowing that in fact Python will be instantiating it anyway always leads me to do the job myself, to be explicit.
Peter Hansen