I think whether to return an error code or throw an exception is something very valid to think about, and a cross-linguistic comparison may be helpful and informative. I guess the very generalized answer to this concern is simply the consideration: that the set of legal return values for any function should be made as small as possible, and as large as necessary.
Generally, this will mean that if a given method returns an integer number in a single test case, users can rightfully expect the method to always return an integer number or throw an exception. But, of course, the conceptually simplest way is not always the best way to handle things.
The return-value-of-least-surprise is usually None
; and if you look into it, you’ll see that it’s the very semantics of None
that license its usage across the board: it is a singleton, immutable value that, in a lot of cases, evaluates to False
or prohibits further computation—no concatenation, no arithmetics. So if you chose to write a frob(x)
method that returns a number for a string input, and None
for non-numeric strings and any other input, and you use that inside an expression like a=42+frob('foo')
, you still get an exception very close to the point where bogus things happened. Of course, if you stuff frob('foo')
into a database column that has not been defined with NOT NULL
, you might run into problems perhaps months later. This may or may not be justifiable.
So in most cases where you e.g. want to derive a number from a string, using somwething like a bare float(x)
or int(x)
is the way to go, as these built-ins will raise an exception when not given a digestable input. If that doesn’t suit your use case, consider returning None
from a custom method; basically, this return value tells consumers that ‘Sorry, I was unable to understand your input.’. But you only want to do this if you positively know that going on in your program does make sense from that point onwards.
You see, I just found out how to turn each notice, warning, and error message into a potentially show-stopping exception in, uhm, PHP. It just drives me crazy that a typo in a variable name generates in the standard PHP configuration, nothing but a notice to the user. This is so bad. The program just goes on doing things with a program code that does not make sense at all! I can’t believe people find this a feature.
Likewise, one should view it like this: if, at any given point in time, it can be asserted with reasonable costs that the execution of a piece of code does no more make sense — since values are missing, are out of bounds, or are of an unexpected type, or when resources like a database connection have gone down — it is imperative, to minimize debugging headaches, to break execution and hand control up to any level in the code which feels entitled to handle the mishap.
Experience shows that refraining from early action and allowing bogus values to creep into your data is good for nothing but making your code harder to debug. So are many examples of over-zealous type-casting: allowing integers to be added to floats is reasonable. To allow a string with nothing but digits to be added to a number is a bogus practice that is likely to create strange, unlocalized errors that may pop up on any given line that happens to be processing that data.