Re: Pythonic API design: detailed errors when you usually don't care
- From: jjl@xxxxxxxxx (John J. Lee)
- Date: 03 Oct 2006 19:32:15 +0100
"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
.
- References:
- Pythonic API design: detailed errors when you usually don't care
- From: Simon Willison
- Pythonic API design: detailed errors when you usually don't care
- Prev by Date: Re: PATCH: Speed up direct string concatenation by 20+%!
- Next by Date: Re: Looping over a list question
- Previous by thread: Re: Pythonic API design: detailed errors when you usually don't care
- Next by thread: zeta function for complex argument
- Index(es):
Relevant Pages
|