Thanks to all for the answers. Sounds like exceptions are most
definitely the way to go, and I will definitely put them in. In fact,
this should make the wrapper a bit cleaner since I am not constantly
checking for errors in variables and returning empty objects. Besides,
I wouldn't want my soul stolen by angry programmers and doomed to
working on Windows, let alone kernel debugging... :) Now, if it were
Android, there might be something to the idea.

On 2/3/11, Steven D'Aprano <st...@pearwood.info> wrote:
> 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  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>


-- 
Have a great day,
Alex (msg sent from GMail website)
mehg...@gmail.com; http://www.facebook.com/mehgcap
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to