views:

750

answers:

13

Brian Kernighan was asked this question in a recent interview. I'll quote his reply:

Brian: I'm torn on this. Error-handling code tends to be bulky and very uninteresting and uninstructive, so it often gets in the way of learning and understanding the basic language constructs. At the same time, it's important to remind programmers that errors do happen and that their code has to be able to cope with errors.

My personal preference is to pretty much ignore error handling in the earlier parts of a tutorial, other than to mention that errors can happen, and similarly to ignore errors in most examples in reference manuals unless the point of some section is errors. But this can reinforce the unconscious belief that it's safe to ignore errors, which is always a bad idea.

I often leave off error handling in code examples here and on my own blog, and I've noticed that this is the general trend on Stack Overflow. Are we reinforcing bad habits? Should we spend more time polishing examples with error handling, or does it just get in the way of illustrating the point?

+1  A: 

Not often I disagree with BWK, but I think beginner examples especially should show error handling code, as this is something that beginners have great difficulty with. More experienced programmers can take the error handling as read.

anon
+5  A: 

Any provided example code will be copy-pasted into production code at least once, so be at your best when writing it.

Simon Svensson
Anyone who does this may just deserve what they get. :-)
tvanfosson
...not that I would intentionally write crap, but you ought to understand any code that you're putting into production not just copy/paste code from some random stranger.
tvanfosson
+1 example code needs to be production quality. How else are people supposed to learn good pratices.
Joachim Sauer
+1  A: 

Error handling is a paradigm by itself; it normally shouldn't be included in examples since it seriously corrupts the point that the author tries to come across with.

If the author wants to pass knowledge about error handling in a specific domain or language then I would prefer as a reader to have a different chapter that outlines all the dominant paradigms of error handling and how this affects the rest of the chapters.

Konstantinos
This is my feeling, both when reading and writing. I feel that error-handling code gets in the way, but a small voice in the back of my mind wonders if I'm doing the reader a disservice by not including it.
Bill the Lizard
+9  A: 

I think it might be an improvement if when posting example code we at least put comments in that say you should put error handling code in at certain spots. This might at least help somebody using that code to remember that they need to have error handling. This will keep the extra code for error handling out but will still reinforce the idea that there needs to be error handling code.

b_richardson
it also shows what errors to catch sometimes, eg a return code that is 0 for success would show "if (code() != 0) then handle_error_here"
gbjbaanb
+5  A: 

Beyond the question of cluttering the code when you're demonstrating a coding point, I think the question becomes, how do you choose to handle the error in your example code?

That is to say, what do you do ? What's fatal for one application is non-fatal for another. e.g. if I can't retrieve some info from a webserver (be it a 404 error or a non-responsive server) that may be fatal if you can't do anything without that data. But if that data is supplementary to what you're doing, then perhaps you can live without it.

So the above may point to simply logging the error. That's better than ignoring the error completely. But I think often the difficulty is in knowing how/when (and when not) to recover from an error. Perhaps that's a whole new tutorial in itself.

Brian Agnew
+2  A: 

I think the solution is somewhere in the middle. If you are defining a function to find element 'x' in list 'y', you do something like this:

function a(x,y) 
{
   assert(isvalid(x))
   assert(isvalid(y))
   logic()
}

There's no need to be explicit about what makes an input valid, just that the reader should know that the logic assumes valid inputs.

Oliver N.
+1 for compromise. I like this solution for input validation, but I wonder how it would scale for something like the error handling needed for a simple TCP client.
Bill the Lizard
+1  A: 

One idea I had would be to include a line like the following in your example code somewhere:

DONT_FORGET_TO_ADD_ERROR_CHECKING();   // You have been warned!

All this does is prevent the code compiling "off the bat" for anyone who just blindly copies and pastes it (since obviously DONT_FORGET_TO_ADD_ERROR_CHECKING() is not defined anywhere). But it's also a hassle, and might be deemed rude.

j_random_hacker
I like the general idea behind this. I suspect that many would just comment the line out, but at least you've forced them to pause and think.
Bill the Lizard
@Bill: Yes, it's really just a way of offloading responsibility for whatever havoc the code might otherwise cause ;) A bit like having to click "Yes, I have read the EULA terms and I agree" before installing something.
j_random_hacker
I'd hope it'd have more of an effect than clicking yes to a EULA, otherwise for most it wouldn't be too helpful :p
Davy8
+1  A: 

I would say that it depends on the context. In a blog entry or text book, I would focus on the code to perform or demonstrate the desired functionality. I would probably give the obligatory nod to error handling, perhaps, even put in a check but stub the code with an ellipsis. In teaching, you can introduce a lot of confusion by including too much code that doesn't focus directly on the subject at hand. In SO, in particular, shorter (but complete) answers seem to be preferred so handling errors with "a wave of the hand" may be more appropriate in this context as well.

That said, if I made a code sample available for download, I would generally make it as complete as possible and include reasonable error handling. The idea here is that for learning the person can always go back to the tutorial/blog and use that to help understand the code as actually implemented.

In my personal experience, this is one of the issues that I have with how TDD is typically presented -- usually you only see the tests developed to check that the code succeeds in the main path of execution. I would like to see more TDD tutorials include developing tests for alternate (error) paths. This aspect of testing, I think, is the hardest to get a handle on since it requires you to think, not of what should happen, but of all the things that could go wrong.

tvanfosson
+1  A: 

One approach I've seen, notably in Advanced Programming in the UNIX Environment and UNIX Network Programming is to wrap calls with error checking code and then use the wrappers in the example code. For instance:

ssiz_t Recv(...)
{
    ssize_t result;
    result = recv(...);
    /* error checking in full */
}

then, in calling code:

Recv(...);

That way you get to show error handling while allowing the flow of calling code to be clear and concise.

dwc
At first I was annoyed by all those non-library includes and function calls in UNP, but they do serve a valuable purpose. :)
Bill the Lizard
... erm. this isn't proper error handling, it can't react adequately to exceptional conditions. all it can do is log and abort...
"Proper" depends too much on context for any such scheme to work. True enough. However, it's entirely appropriate for example code as found in APUE and UNP. First, it shows how to examine and react to return status. Second, it shows the flow of example code without the bulk of error checking.
dwc
+3  A: 

Examples should be illustrative. They should always show the point being made clearly with as little distraction as possible. Here's a meta-example:

Say we want to read a number from a file, add 3, and print it to the console. We'll need to demonstrate a few things.

infile = file("example.txt")
content = infile.read()
infile.close()
num = int(content)
print (3 + num)

wordy, but correct, except there are a few things that could go wrong. First, what if the file didn't exist? What if it does exist but doesn't contain a number?

So we show how the errors would be handled.

try:
    infile = file("example.txt")
    content = infile.read()
    infile.close()
    num = int(content)
    print (3 + num)
except ValueError:
    print "Oops, the file didn't have a number."
except IOError:
    print "Oops, couldn't open the file for some reason."

After a few iterations of showing how to handle the errors raised by, in this case, file handling and parsing. Of course we'd like to show a more pythonic way of expressing the try clause. Now we drop the error handling, cause that's not what we're demonstrating.

First lets eliminate the unneeded extra variables.

infile = file("example.txt")
print (3 + int(infile.read()))
infile.close()

Since we're not writing to it, nor is it an expensive resource on a long-running process, it's actually safe to leave it open. It will closewhen the program terminates.

print ( 3 + int(file("example.txt").read()))

However, some might argue that's a bad habit and there's a nicer way to handle that issue. We can use a context to make it a little clearer. of course we would explain that a file will close automatically at the end of a with block.

with file("example.txt") as infile:
    print (3 + int(infile.read()))

And then, now that we've expressed everything we wanted to, we show a complete example at the very end of the section. Also, we'll add some documentation.

# Open a file "example.txt", read a number out of it, add 3 to it and print
# it to the console.
try:
    with file("example.txt") as infile:
        print (3 + int(infile.read()))
except ValueError: # in case int() can't understand what's in the file
    print "Oops, the file didn't have a number."
except IOError: # in case the file didn't exist.
    print "Oops, couldn't open the file for some reason."

This is actually the way I usually see guides expressed, and it works very well. I usually get frustrated when any part is missing.

TokenMacGuy
This is what I like to see in books, where the author can spend a chapter, or at least several pages, polishing an example.
Bill the Lizard
A: 

No, unless the purpose of the example is to demonstrate an aspect of exception handling. This is a pet peeve of mine -- many examples try to demonstrate best practices and end up obscuring and complicating the example. I see this all the time in code examples that start by defining a bunch of interfaces and inheritance chains that aren't necessary for the example. A prime example of over complicating was a hands-on lab I did at TechEd last year. The lab was on Linq, but the sample code I was directed to write created a multi-tier application for no purpose.

Examples should start with the simplest possible code that demonstrates the point, then progress into real-world usage and best practices.

As an aside, when I've asked for code samples from job candidates almost all of them are careful to demonstrate their knowledge of exception handling:

public void DoSomethingCool()
{
    try
    {
         // do something cool
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

I've received hundreds of lines of code with every method like this. I've started to award bonus points for those that use throw; instead of throw ex;

Jamie Ide
+1  A: 

I don't think error handling should be in the example if it obscures the logic. But some error handling is just the idiom of doing some things, and in theese case include it.

Also if pointing out that error handling needs to be added. For the love of deity also point out what errors needs to be handled.

This is the most frustrating part of reading some examples. If you don't know what you are doing (which we have to assume of the reader of the example...) you don't know what errors to look for either. Which turns the "add error handling" suggestion into "this example is useless".

John Nilsson
A: 

Sample code need not include error handling but it should otherwise demonstrate proper secure coding techniques. Many web code snippets violate the OWASP Top ten.

jm04469