Defining error codes - exception

Is there a "right way" to define error codes? I mean, I've built a library a while ago that throws custom exceptions, but I targeted the custom error messages to a developer's standpoint. Now I'm wrapping up the GUI and when I catch those exceptions, I need more user friendly messages. That's not a problem in itself, but let's say, I have my ReceiverNotAvailableException exception and NoMessageReceivedException. To me, as a developer, they mean completely different things and have different inner messages, but to the end-user they just mean "User not found". I'd like to display something like "User not found (error X)" where X varies depending on which exception is raised - pretty commonplace if you ask me.
My question is: should I go with X=1, 2 and so forth depending on what kind of exception or should I opt for something more complicated for whatever reason? I know it sounds like a dumb question, but I'd really like to know what the "best practice" (I'm not so fond of the term) is in this case.
BTW, of course I'd have a table mapping each code to its corresponding exception, whichever the case is.

If your exceptions can't overlap, then going with a HashTable[ExceptionName] = "Error Message" looks like a sane option. If they can you can use something like the following:
The standard way to define message codes that can overlap (this is, occur at the same time) is to use powers of two:
define ERROR_SYSTEM_DOWN 1
define ERROR_DATABASE_UNREACHABLE 2
define ERROR_SPACE_UNAVAILABLE 4
define ERROR_DISK_DIED 8
and so on. Then, in code you can do
if (disk_died() && no_space()) {
int errorCode = ERROR_DISK_DIED | ERROR_SPACE_UNAVAIABLE; //Binary or
return errorCode;
}
Finally, on the receiving end you can:
if (errorCode & ERROR_DISK_DIED == ERROR_DISK_DIED) { //Binary and
//then, at least, disk died. You can check for the rest in the same way
}
Explanation:
ERROR_SYSTEM_DOWN = 0001
ERROR_DATABASE_UNREACHABLE = 0010
ERROR_SPACE_UNAVAILABLE = 0100
ERROR_DISK_DIED = 1000
Then
1000 | 0100 = 1100
and, on the checking code
1100 & 0100 = 0100
Now, if you are using exceptions you can use the same approach, bubbling up the errorCode as long as exception occur. Although this idiom is more common in C.

Related

Ensuring that a predicate succeeds deterministically

This other question asks almost the same, but not quite. Rather, how do I demand that a goal succeeds deterministically (exactly once) and does not leave behind any choice points?
This is especially useful in the context of Prolog programs that are used as command-line tools: possibly read from standard input, take arguments, and write to standard output. In such a program, leaving a choice point after doing the work is invariably an error of the programmer.
SWI-Prolog offers deterministic/1, so one could write:
( deterministic(true)
-> true
; fail
)
Another, more portable way to achieve the same was suggested:
is_det(Goal, IsDet) :-
setup_call_cleanup(true, Goal, Det=true),
( Det == true
-> IsDet = true
; !,
IsDet = false
).
However, it seems useful to throw an error when this happens, but I don't know what this error would be. I looked quite carefully through the ISO error terms and I could not find an error that would obviously describe this situation.
Is it indeed better to throw an error, or should I just fail? If throwing an error is to be preferred, what would that error be?
EDIT: I am not sure what to because especially when side effects are involved, like writing something to standard output, it feels very wrong to have the side effect happen and then fail. It is almost necessary to rather throw an exception. This makes it also possible to decide that the remaining choice point is harmless (if not desirable) and just catch the exception, then write to standard error or return a different exit code.
But I really have no idea what describes the exception properly, so I don't know what term to throw.
Check out call_semidet/1 as proposed by Ulrich Neumerkel on the SWI-Prolog mailing list:
call_semidet/1 - clean removal of choice-points
In it, he proposes:
call_semidet(Goal) :-
( call_nth(Goal, 2)
-> throw(error(mode_error(semidet,Goal),_))
; once(Goal)
).
This proposed mode_error is a very good start.
In spirit, it follows the other errors: In this case, mode semidet is expected, and this is reflected in the thrown error term.

Is there any advantage in specifying types of variables and return type of functions?

I always set the types of my variables and functions, a habit I brought from my Java learning, seems the right thing to do.
But I always see "weak typing" in other people's code, but I can't disagree with that as I don't know what are the real advantages of keep everything strong typed.
I think my question is clear, but I gonna give some examples:
var id = "Z226";
function changeId(newId){
id = newId;
return newId;
}
My code would be like this:
var id:String = "Z226";
function changeId(newId:String):String{
id = newId;
return newId;
}
Yes, the big advantanges are:
faster code execution, because the runtime know the type, it does not have to evaluate the call
better tool support: auto completion and code hints will work with typed arguments and return types
far better readability
You get performance benefits from strongly typing. See http://gskinner.com/talks/quick/#45
I also find strongly typed code to be much more readable, but I guess depending on the person they may not care.
As pointed out by florian, two advantages of strongly typing are that development tools can can use the information to provide better code-hinting and code-completion, and that type, as an explicit indicator of how the variable or method is intended to be used, can make the code much easier to understand.
The question of performance seems to be up for debate. However, this answer on stackoverflow suggests that typed is definitely faster than untyped in certain benchmark tests but, as the author states, not so much that you would notice it under normal conditions.
However, I would argue that the biggest advantage of strong typing is that you get a compiler error if you attempt to assign or return a value of the wrong type. This helps prevent the kind of pernicious bug which can only be tracked down by actually running the program.
Consider the following contrived example in which ActionScript automatically converts the result to a string before returning. Strongly typing the method's parameter and return will ensure that the program will not compile and a warning is issued. This could potentially save you hours of debugging.
function increment(value) {
return value + 1;
}
trace(increment("1"));
// 11
While the points in the other answers about code hinting and error checking are accurate, I want to address the claim about performance. It's really not all that true. In theory, strong type allows the compiler to generate code that's closer to native. With the current VM though, such optimization doesn't happen. Here and there the AS3 compiler will employ an integer instruction instead of a floating point one. Otherwise the type indicators don't have much effect at runtime.
For example, consider the following code:
function hello():String {
return "Hello";
}
var s:String = hello() + ' world';
trace(s);
Here're the AVM2 op codes resulting from it:
getlocal_0
pushscope
getlocal_0
getlocal_0
callproperty 4 0 ; call hello()
pushstring 12 ; push ' world' onto stack
add ; concatenate the two
initproperty 5 ; save it to var s
findpropstrict 7 ; look up trace
getlocal_0 ; push this onto stack
getproperty 5 ; look up var s
callpropvoid 7 1 ; call trace
returnvoid
Now, if I remove the type indicators, I get the following:
getlocal_0
pushscope
getlocal_0
getlocal_0
callproperty 3 0
pushstring 11
add
initproperty 4
findpropstrict 6
getlocal_0
getproperty 4
callpropvoid 6 1
returnvoid
It's exactly the same, except all the name indices are one less since 'String' no longer appears in the constant table.
I'm not trying to discourage people from employing strong typing. One just shouldn't expect miracle on the performance front.
EDIT: In case anyone is interested, I've put my AS3 bytecode disassembler online:
http://flaczki.net46.net/codedump/
I've improved it so that it now dereferences the operands.

Throw extra exception to avoid code duplication

First of all, I know the standard answer will be that exceptions are never to be used for flow control. While I perfectly agree with this, I've been thinking a long time about something I sometimes did, which I'll describe with the following pseudo-code:
try
string keyboardInput = read()
int number = int.parse(keyboardInput)
//the conversion succeeds
if(number >= 1000)
//That's not what I asked for. The message to display to the user
//is already in the catch-block below.
throw new NumberFormatException() //well, there IS something wrong with the number...
catch(NumberFormatException ex) //the user entered text
print("Please enter a valid number below 1000.")
First of all, take this example in a very abstract way. This does not necessarily have to happen. The situation simply is:
A user input needs to be constrained and can go wrong in 2 ways,
either
by a thrown exception the language defines, or by a check. Both errors
are reported by the user in the same way, because they do not need to know
the technical difference of what caused it.
I have thought of several ways to solve it. To begin with, it would be better to throw a custom made exception. The problem I then face is, if I catch it locally, what to do with the other exception? In se, the custom exception would be cause for a second catch-block, in which the message would be copied into just as well. My solution:
//number is wrong
throw new MyException()
catch(NumberFormatException ex)
throw new MyException()
catch(MyException ex) {
print("Please enter...")
The meaning of the exceptions' names is everything here. This application of custom-made exceptions is widely accepted, but essentially I didn't do anything different from the first way: I forced to go into a catch-block, albeit by throwing a custom exception rather than a standard-library one.
The same way applied to throwing the exception on to the calling method (thus not having a catch block for the custom exception) seems to make more sense. My method can go wrong in what is technically two ways, but essentially one way: wrong user input. Therefore, one would write a UserInputException and make the method throw this. New problem: what if this is the main method of an application?
I'm not currently struggling with a specific application to implement this kind of behaviour, my question is purely theoretical and non-language specific.
What is the best way to approach this?
I would consider the first exception to be low-level, and I would handle it (by translation in this case) at the point of call. I find that this leads to code that is easier to maintain and refactor later, as you have less types of exceptions to handle.
try
string keyboardInput = read()
try
int number = int.parse(keyboardInput)
catch(NumberFormatException ex)
throw MyException("Input value was not a number")
//the conversion succeeds
if(number >= 1000)
throw MyException("Input value was out of range")
catch(MyException ex) //the user entered text
print( ex.ToString() )
print("Please enter a valid number below 1000.")
I think you have essentially a few ways to go about it with minimal code duplication in mind:
Use a boolean variable/store the exception: If there was an error anywhere in the the general logic of the specific task you are performing, you exit on the first sign of error and handle that in a separate error handling branch.
Advantages: only one place to handle the error; you can use any custom exception/error condition you like.
Disadvantages: the logic of what you are trying to achieve might be hard to discover.
Create a general function that you can use to inform the user about the error (pre-calculating/storing all information that describes the general error, e.g. the message to display the user), so you can just make one function call when an error condition happens.
Advantages: the logic of your intent might be clearer for readers of the code; you can use anu custom exception/error conditon you like.
Disadvantages: the error will have to be handled in separate places (although with the pre-computed/stored values, there is not much copy-paste, however complex the informing the user part).
If the intent is clear, I don't think throwing exceptions from within your try block explicitly is a bad idea. If you do not want to throw one of the system provided exceptions, you can always create your own that derives from one of them, so you only need a minimal number (preferably one) of catch blocks.
Advantages: only one place to handle error condition -- if there is essentially only one type of exception thrown in try-block.
Disadvantages: if more than one type of exception is thrown, you need nested try-catch blocks (to propagate the exceptions to the most outward one) or a very general (e.g. Exception) catch block to avoid having to duplicate error reporting.
The way I see it is this:
Assuming there's no other way to parse your int that doesn't throw an exception, your code as it is now, is correct and elegant.
The only issue would be if your code was in some kind of loop, in which case you might worry about the overhead of throwing and catching unnecessary exceptions. In that case, you will have to compromise some of your code's beauty in favor of only handling exceptions whenever necessary.
error=false;
try {
string keyboardInput = read();
int number = int.parse(keyboardInput);
//the conversion succeeds
if(number >= 1000) {
//That's not what I asked for. The message to display to the user
//is already in the catch-block below.
error=true;
} catch(NumberFormatException ex) { //the user entered text
error=true;
}
if (error)
print("Please enter a valid number below 1000.");
Also you can think about why you're trying to aggregate two errors into one.
Instead you could inform the user as to what error they did, which might be more helpful in some cases:
try {
string keyboardInput = read();
int number = int.parse(keyboardInput);
//the conversion succeeds
if(number >= 1000) {
//That's not what I asked for. The message to display to the user
//is already in the catch-block below.
print("Please enter a number below 1000.");
} catch(NumberFormatException ex) { //the user entered text
print("Please enter a valid number.");
}
You do not need any exceptions in this particular example.
int number;
if (int.TryParse(keyboardInput, out number) && number < 1000) // success
else // error
However, the situation you describe is common in business software, and throwing an exception to reach a uniform handler is quite common.
One such pattern is XML validation followed by XSLT. In some systems, invalid XML is handled through catching validation exceptions. In these systems, it is pretty natural to reuse the existing exception handling in XSLT (which can naturally detect some classes of data errors that a particular validation language cannot):
<xsl:if test="#required = 'yes' and #prohibited = 'yes'>
<xsl:message terminate='yes'>Error message</xsl:message>
</xsl:if>
It is important to see that if such conditions are extremely rare (expected to occur only during early integration testing, and disappear as defects in other modules get fixed), most of the typical concerns around not using exceptions for flow control do not really apply.
What about approaching this validation problem by writing several validator classes that take in an input and return errors, or no errors. As far as your struggle with exceptions: put that logic into each validator and deal with it there on a case by case basis.
after that you figure out the correct validators to use for your input, collect their errors and handle them.
the benefits of this are:
Validators do one thing, validate a single case
Its up to the validation function to decide how to handle the errors. Do you break on first validation error or do you collect them all and then deal with them?
You can write your code is such a way that the main validation function can validate different types of input using the same code, just picking the correct validators using your favorite technique.
and disadvantages:
You will end up writing more code (but if you are using java, this should be put into the 'benefits' bucket)
here is some example pseudo-code:
validate(input):
validators = Validator.for(input.type)
errors = []
for validator in validators:
errors.push(validator.validate(input))
if errors:
throw PoopException
and some validators:
MaxValidator extends IntValidator:
validate(input):
errors = []
errors.push(super.validate(input))
if input > 1000:
errors.push("bleee!!!! to big!")
return errors
IntValidator:
validate(input):
try:
int.parse(input)
catch NumberFormatException:
return ['not an int']
return []
of course you would need to do some trickery to make the parent validator possibly return you a valid version of the input, in this case string "123" converted to an int so the max validator can handle it, but this can be easily accomplished by making the validators statefull or some other magic.
I can't see this answer anywhere in here, so I'll just post it as another point of view.
As we all know, you can actually break the rules if you know them well enough, so you can use throwing an Exception for flow control if you know it's the best solution for your situation. From what I've seen, it happens usually with some dumb frameworks...
That said, before Java 7 (which brought us the mighty multicatch construct), this was my approach to avoid code repetition:
try {
someOffendingMethod();
} catch (Exception e) {
if (e instanceof NumberFormatException || e instanceof MyException) {
System.out.println("Please enter a valid number.");
}
}
It's a valid technique in C#, too.

Elegant way to handle "impossible" code paths

Occasionally I'll have a situation where I've written some code and, based on its logic, a certain path is impossible. For example:
activeGames = [10, 20, 30]
limit = 4
def getBestActiveGameStat():
if not activeGames: return None
return max(activeGames)
def bah():
if limit == 0: return "Limit is 0"
if len(activeGames) >= limit:
somestat = getBestActiveGameStat()
if somestat is None:
print "The universe has exploded"
#etc...
What would go in the universe exploding line? If limit is 0, then the function returns. If len(activeGames) >= limit, then there must be at least one active game, so getBestActiveGameStat() can't return None. So, should I even check for it?
The same also happens with something like a while loop which always returns in the loop:
def hmph():
while condition:
if foo: return "yep"
doStuffToMakeFooTrue()
raise SingularityFlippedMyBitsError()
Since I "know" it's impossible, should anything even be there?
If len(activeGames) >= limit, then
there must be at least one active
game, so getBestActiveGameStat() can't
return None. So, should I even check
for it?
Sometimes we make mistakes. You could have a program error now -- or someone could create one later.
Those errors might result in exceptions or failed unit tests. But debugging is expensive; it's useful to have multiple ways to detect errors.
A quickly written assert statement can express an expected invariant to human readers. And when debugging, a failed assertion can pinpoint an error quickly.
Sutter and Alexandrescu address this issue in "C++ Coding Standards." Despite the title, their arguments and guidelines are are language agnostic.
Assert liberally to document internal assumptions and invariants
... Use assert or an equivalent liberally to document assumptions internal to a module ... that must always be true and otherwise represent programming errors.
For example, if the default case in a switch statement cannot occur, add the case with assert(false).
IMHO, the first example is really more a question of how catastrophic failures are presented to the user. In the event that someone does something really silly and sets activeGames to none, most languages will throw a NullPointer/InvalidReference type of exception. If you have a good system for catching these kinds of errors and handling them elegantly, then I would argue that you leave these guards out entirely.
If you have a decent set of unit tests, they will ensure with huge amounts of certainty that this kind of problem does not escape the developers machine.
As for the second one, what you're really guarding against is a race condition. What if the "doStuffToMakeFooTrue()" method never makes foo true? This code will eventually run itself into the ground. Rather than risk that, I'll usually put code like this on a timer. If your language has closures or function pointers (honestly not sure about Python...), you can hide the implementation of the timing logic in a nice helper method, and call it this way:
withTiming(hmph, 30) // run for 30 seconds, then fail
If you don't have closures or function pointers, you'll have to do it the long way everywhere:
stopwatch = new Stopwatch(30)
stopwatch.start()
while stopwatch.elapsedTimeInSeconds() < 30
hmph()
raise OperationTimedOutError()

Catching Exception, do's and dont's

Is it always a bad programming technique to leave a catch block empty when using a try-catch block?
In cases where I am expecting an exception, for example, I am reading 10 values from a file...and converting each value into a String. There is a possibility that one of the 10 values can be a null, but I don't want to stop my execution at that point and rather continue (obvious use of try catch)
A lame example of what I am trying:
String _text = textReader.ReadLine(); //Assuming this RETURNS a NULL value
try {
String _check = _text.ToString();
//Do something with _check, but it should not be NULL
}
catch (Exception)
{ //Do Nothing }
At this point, when I catch an exception:
1. I don't want to log this. Since I am expecting a buggy value.
2. I don't want to re-throw the exception up the call-stack.
3. I want to simply continue with my execution
Under these cases, is it acceptable to leave the catch empty? Or is this a complete NO-NO and there is a better way to handle this?
I presume this can be a community wiki since it also deals with programming techniques.
- Ivar
I assume that you mean
_text.ToString()
and you're concerned about the case when _text may be null?
I don't like your use of exceptions in this case. Put yourself in the mind of someone needing to maintain this code. They see:
catch (Exception) { }
Can they really deduce that all this is doing is catching the Null case? They have to consider what other Exceptions might be thrown. At the very least this raises uncertainty in the maintainer's mind.
Why could you not code:
if ( _text != null ) {
String _check = _nullValue.ToString();
}
This says exactly what you mean.
But taking this further, what does getting a value of NULL mean? You're reading a file that may have 10 values in it. I'm guessing that maybe blank line gives a null for you?
What do intend if you get:
1
2
<blank line>
4
...
10
So that's 9 good values and a blank line. What will you do if instead you get 10 good values and a blank line? 11 good values? 11 good values and a blank line?
My point is that silently ignoring oddities in user input is often a bad idea. It's quite likely that some of the cases above are actually typos. By warning in some of these cases you may be very helpful to the user. This implies that probably most odditities in input need at least some kind of count, if not an actual immediate error log.
You might, for example, emit a message at the end
Your file contained 13 lines, two lines were blank. We processed 10 valid values and ignored one.
At the very leasyt for debugging purposes you might have trace statements in the error paths.
Summary: completely ignoring Exceptions is rarely the right thing to do.
If it's expected it's not really exceptional. Is this a good use of exceptions? It may be more appropriate to test for a null value before trying to do stuff.
if(_text != null)
// do something
The best argument I liked was that the code will become highly un-maintainable. And my aim was to make my code as easy to understand as possible.
With the suggestions above, I have an army of ternary operators in place (my personal favorite over big if-else blocks).
And the code definitely looks better! and I think unless the try-catch is well documented, I don't myself see a good reason for having empty catch statements anymore.
Thanks Guys!!
-Ivar