Reputation: 42757
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?
Upvotes: 1
Views: 1563
Reputation: 375634
@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.
Upvotes: 1
Reputation: 1321
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.
Upvotes: 3