Re: Pythonic API design: detailed errors when you usually don't care



"Simon Willison" <swillison@xxxxxxxxx> writes:

Hi all,

I have an API design question. I'm writing a function that can either
succeed or fail. Most of the time the code calling the function won't
care about the reason for the failure, but very occasionally it will.

I can see a number of ways of doing this, but none of them feel
aesthetically pleasing:

1.

try:
do_something()
except HttpError:
# An HTTP error occurred
except ApplicationError:
# An application error occurred
else:
# It worked!

This does the job fine, but has a couple of problems. The first is that
I anticipate that most people using my function won't care about the
reason; they'll just want a True or False answer. Their ideal API would
look like this:

if do_something():
# It succeeded
else:
# It failed

The second is that the common path is success, which is hidden away in
the 'else' clause. This seems unintuitive.

It's hard to answer this without knowing any of the real details
you've hidden from us: I'm not sure I believe you that the code at the
call site necessarily needs to know whether the function call
succeeded at all. Perhaps the preferred usage might sometimes be:

do_something()


Exceptions raised may be caught (or not, if the application does not
find that necessary), elsewhere than at the call site -- they can be
caught further up the stack. You are of course aware of this fact,
but your discussion seems to imply that this crucial piece of
knowledge was not active in your mind when you wrote it.

I think Python users are right to "default to" raising exceptions.
There's a nice label for this practice:

http://c2.com/cgi/wiki?SamuraiPrinciple

"""
Samurai Principle

Return victorious, or not at all.
"""


:-)

(though I imagine that term is used with subtly different meanings by
different people...)


As others have suggested, often it is useful if most exceptions that
can be raised by a callable are instances of a single class. This can
be achieved through inheritance (make them all derive from one class)
or composition (stuff the various original exceptions into a wrapper
exception).


John

.



Relevant Pages

  • Re: Agent 3.0 Woof
    ... Record companies spend piles of money on producing 'monster' hits. ... few exceptions, the only way you can get monster hits is by selling a ... Classical enthusiasts care about this because slow-and-steady earners ...
    (rec.music.classical.recordings)
  • Re: testing parent-child relations using only ids
    ... And exceptions are *necessary*: Without them, ... I don't care about the exceptions *themselves*; ... I was kidding a bit about the wonders of macros. ... should try to flame in their forum; I'll bet you'd get stomped on. ...
    (comp.lang.cpp)
  • Re: Man, did I put the fox in amongst the chickens...
    ... reason to care about them, but I don't see why they should care about ... I'm trying to imagine myself getting bored of hearing "I really liked ... admire is usually rewarding (there are exceptions, ... exceptions I usually just sigh and walk away). ...
    (rec.arts.sf.composition)
  • Re: Is necessary to switch to C++ or some object-oriented language?
    ... It's very rare for programs ... to need to call mainrecursively, or to care about the type of a ... Rename all of the .c files to .cpp and try to compile it. ... exceptions are widely used, ...
    (comp.lang.c)
  • Re: How to determine what exceptions a method might raise?
    ... Just calling 'file' the most obvious exceptions it can raise are: ... few different exceptions doesn't mean that the line of code calling it ... cannot generate a host more. ...
    (comp.lang.python)