views:

109

answers:

3

Is it OK to raise a built-in exception with a custom text? or to raise a built-in warning also with custom text?

The documentation reads:

exception ValueError: Raised when a built-in operation or function receives an argument (…)

Is it implied that only built-in operations should raise a ValueError exception?

In practice, I understand that it is safe to create an exception class that inherits from ValueError or Exception. But is it OK not to do that, and directly raise a ValueError("custom text")?

Since ValueError is built-in, raising a ValueError (with a custom text) allows users to quickly see what kind of problem is involved, compared to a custom exception type (something like "ValueErrorSpecificModule", which is not standard).

+2  A: 

It's perfectly ok.

However you may want to create your own subclass to help distinguish from the builtin exceptions

For example if you have something that works like a dict, you can raise a KeyError for the usual reasons, but what if the KeyError is really coming from an underlying dict you are using in the implementation.

Raising a subclass of KeyError makes it easier to see that there is a bug in the implementation, and not that the key just isn't in your object

gnibbler
+2  A: 

It's OK and I do it all the time. I find it less surprising to see TypeError than MySpecialTypeError in many situations.

On the page you linked, I don't see the phrase "built-in":

exception TypeError: Raised when an operation or function is applied to an object of inappropriate type. The associated value is a string giving details about the type mismatch.

Perhaps someone saw your question and fixed the documentation already.
EDIT: It looks like you may have inserted the documentation for ValueError instead of TypeError

Christopher Bruns
Good catch. Thanks!
EOL
+5  A: 

There's nothing operationally wrong with doing something like:

raise ValueError("invalid input encoding")

In fact, I do that quite often when I'm writing the first pass of some code. The main problem with doing it that way is that clients of your code have a hard time being precise in their exception handling; in order to catch that specific exception, they would have to do string matching on the exception object they caught, which is obviously fragile and tedious. Thus, it would be better to introduce a ValueError subclass of your own; this could still be caught as ValueError, but also as the more specific exception class.

A general rule of thumb is that whenever you have code like:

raise ValueError('some problem: %s' % value)

You should probably replace it with something like:

class SomeProblem(ValueError):
    """
    Raised to signal a problem with the specified value.
    """
# ...
raise SomeProblem(value)

You might say that the exception type specifies what went wrong, whereas the message / attributes specify how it went wrong.

mithrandi