How do I know all thrown exceptions of a function?

Remco Gerlich scarblac at pino.selwerd.nl
Wed Jan 24 10:04:58 EST 2001


Paul Foley mailed me his comments, I'm assuming he meant to post to the
group. I'll paste in some of them, since he disagreed interestingly :-)
(his quotes marked with |)

I've left D-Man's comments in although I comment mainly on Paul's, but
whatever :)

D-Man <dsh8290 at rit.edu> wrote in comp.lang.python:
> On Tue, Jan 23, 2001 at 06:48:45PM +0000, Remco Gerlich wrote:
 > | - All the exceptions your code explicitly throws should inherit
> |   some base exception defined in your module, so that that can
> |   be tested for.
> 
> I agree with this.  It makes handling all exceptions of a certain
> classification easy.

(Paul)
| No.  If your code gets, say, a bad value, it should raise ValueError,
| not some new version of ValueError defined only in that module.

Ah, of course. If there's an obvious builtin exception for exactly this
problem, use that. That should cover many cases.

My point is though, say you have some markup language parser that is looking
for an end tag. Your string.index() call fails with a ValueError (end marker
not found). Now it would be best to catch that and raise some sort of
mymarkupparser.MissingEndTag exception, not to simply pass on the unhelpful
ValueError that might change once you switch to regular expressions.

(Paul)
| It's often useful to define a bunch of new exceptions for your module,
| but probably equally often, you want the built-in exceptions [or,
| occasionally, exceptions defined in third-party modules you imported.
| E.g., a module that defines some new kind of network socket might want
| to raise socket.error...though this is a bad example; socket.error is
| rather under-specific...]

I don't like using exceptions from completely different modules you happen
to use. That is where it becomes hard to find out for the user what
exceptions your code might raise, and now they need to import that module to
use its exceptions, and read its documentation, when the whole points is
that they reach it through your module so they don't have to know about it.

> | - Avoid throwing exceptions that have to do with your implementation
> |   to the outside world. If your module function gets an argument that
> |   is out of range, resulting in an IndexError, don't just pass that on
> |   to the caller but catch it and raise a custom exception yourself,
> |   that inherits from your module's standard exception. Hide your
> |   implementation.
> 
> I agree with this as well.  I did this when modifying a library to
> actually throw exceptions :-).  It had try{ ... } catch( Exception e ) {
> return false ; } in it.  (Java lib someone else copied from a C lib).
> It made the errors much more useful.
 
(Paul)
| Au contraire; pass on that IndexError if it makes sense to do so
| (i.e., if you can't handle it inside your code, and its not some
| implementation detail that could go away with a different
| implementation (unlikely, for IndexError)). 

But if it's caused by a bad input value, it should raise ValueError - so you
catch it and raise the other exception. Otherwise you have to remember for
each library function what the exception is that it throws when you give it
wrong input (and there might be several possibilities).

(Paul)
| Catching it only to raise
| some custom exception is conceptually horrible, as well as being
| generally impossible (think higher-level functions, or callbacks.  You
| don't know what the user wants to do when exceptions happen in his own
| code that's being called by yours, and if you alter his exceptions,
| you'll break his handlers!  Utterly evil!)

Ok, functions you know nothing about that are passed in as an argument,
those are an exception. If you know nothing about what it does, you
shouldn't change it either...

(Paul)
| Perhaps the best advice is "know what you're doing, and write code
| that behaves sensibly", rather than trying to enforce some overly
| strict rules.

Of course. But discussing what good rules of thumb would be makes it a
lot easier to behave sensibly later :-).

-- 
Remco Gerlich



More information about the Python-list mailing list