Alex Hall wrote:
Hi all,
I am wondering what the best way to do the following would be: throw
an exception, or always return an object but set an error flag if
something goes wrong?

Raise an exception. Error flags are an anti-pattern -- a software idiom that you should not follow.

The problem with flags is that callers will forget to check them, which leads to problems being revealed far away from where the problem was caused. That makes it *really* hard to debug.

result = function(x)  # fails and sets an error flag in result
do_something_else()
data = [1, 2, 'a', result, 'xyz']  # store
another_function(data)
# ...
# ...
# lots more code here
# ...
# ...
x = data[3]
do_something_with(x)

which then blows up, because x is invalid but you haven't checked the error flag. The problem actually was with the *original* x, all the way back at the start, but that's been thrown away now, never to be seen again, which makes it hard to debug why it failed.

A million, billion, trillion times worse is if you have a single global error flag! That's *disastrous*, because you MUST check the flag *immediately*, otherwise it can be cleared.

x = function(100000000)  # fails
y = another_function(1000)
if global_error_flag:
    # seems to be safe to use x
    process(x)  # but it isn't, and this blows up

the problem being that another_function makes a second call to function(), only this one succeeds and resets the global flag. If you do this, the ghost of a thousand programmers will drag your spirit off to the nether regions of Hell, where you will have to debug the Windows kernel using only the `ed` editor on a keyboard missing the letters "x", "s" and "1" for all of eternity.

For those who don't know the `ed` editor, it is "the standard Unix editor":

http://www.gnu.org/fun/jokes/ed.msg.html



Which is the "standard" way when dealing with objects? Throw
exceptions or always return an object, even if said object has an
error and may therefore not have data beyond an error code and
message? If I go the exception route, can I somehow put a message into
the exception, maybe adding it as an attribute of my custom exception
class? I assume so...
except e:
 print e.message

Most standard is to raise an exception. The syntax is:

raise ValueError("any message you like")

or use whatever error type suits your problem. You can even define your own exception types:

class MyError(ValueError):
    pass


Less common, but still reasonable, is to raise an error sentinel in place of the normal result. For example, re.match() and re.search() return None when there is nothing found, instead of a MatchObject. Another example, str.find() returns -1.

The disadvantage of this is obvious:

>>> string = "Nobody expects the Portuguese Inquisition!"
>>> offset = string.find("Spanish")
>>> print(string[offset:])  # expecting "Spanish Inquisition!"
!


For special purposes, like mathematics, you can define error values that propagate through calculations. Python has half-hearted support for such "Not A Number" codes:

>>> nan = float('nan')
>>> nan + 1  # doesn't fail, but propagates
nan
>>> nan**2
nan
>>> nan - 1000
nan

as well as infinity. But you should consider this a very specialized solution (as well as a lot of work!!!).

Another non-standard solution is to return a pair of values, a flag plus the value you actually want:

flag, value = function(10000)
if flag:
    do_something_with(value)
else:
    process_error()



or something like that. I know I have research to do about the
specifics of all this, but before I go off and look it all up I am
wondering if it is the best way to go as far as standards and best
coding practices. This is still that api wrapper, so I am not the only
one who may end up using this file and I want to make it into
something that is useable and does what people expect. TIA.

Then there is absolutely not even a shadow of a doubt: use exceptions.



--
Steven

_______________________________________________
Tutor maillist  -  [email protected]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to