views:

36

answers:

2

I have custom exceptions in my django project that look like this:

class CustomFooError(Exception):

    def __init__(self, msg="Something went wrong with Foo."):
        self.msg = msg

    def __str__(self):
        return repr(self.msg) 

At various points in my code I will raise exceptions like this:

raise CustomFooError("Things are going badly")

When Django catches these errors, in debug mode I get django's standard pretty stack-trace page. But I never see my error messages -- "Things are going badly" never shows up in the debug error page.

It seems they should show up as the Exception Value on the error page. I walked back through the django source far enough to find out that this is the value field from sys.exc_info() which is consistently tersely documented as "[the exception's] associated value or the second argument to raise, which is always a class instance if the exception type is a class object." Unfortunately, I don't know what to do with this information.

So my question is: How should I be writing and raising my custom exceptions to get more useful data to show up in places like the django error screen?

+4  A: 

I would just use super and let the constructor of Exception handle assigning the msg attribute:

class CustomFooError(Exception):

    def __init__(self, msg=None):
        if msg is None:
            msg = 'Something went wrong with Foo.'
        super(CustomFooError, self).__init__(msg)

I just tested this from within a Django environment and it correctly displayed the message I passed to the exception constructor or the default one if None was passed.

AdmiralNemo
+2  A: 

@AdmiralNemo is right: let the base class do the work.

But to dig into your code a little deeper, the problem is that you don't tie into the Exception implementation at all. Exception(s) stores s in the .message attribute, not .msg. It also stores it as (s,) in the .args attribute. Your code doesn't set either of these attributes, which is probably why Django can't find a message to display.

Also, your __str__ method is odd. It should return self.msg, not repr(self.msg), which would add quotes around the string, and potentially escapes inside the text.

Ned Batchelder
Thanks. I borrowed the exception code from some library figuring they knew more about subclassing Exception than I do.
Leopd