views:

79

answers:

4

When writing code, I find it important that my code looks well (apart from the fact that it has to work well). It is well described in the book Code Complete (p729): 'The visual and intellectual enjoyment of well-formatted code is a pleasure that few nonprogrammers can appreciate'.

The problem is, as soon as I got my code functionally working, and I start to introduce error handling (try-except clauses etc.) to make it robust, I find that this usually messes up my well-laid out code and turns it into something that is definitely not visually pleasing. The try-except statements and additional if's, make the code less readable and structured.

I wonder if this is because I misuse or overuse error handling, or is this unavoidable? Any tips or tricks to keep it good-looking?

A: 

It all depends on how you do your programming. You can avoid a lot of these try-catch (or as you put it, try-except) statements if you just do proper input validation. Sure, it's a lot of work to cover most of the junk users tend to put into forms etc, but it will keep your data handling routines clean (or cleaner).

Gert G
+5  A: 

It is hard to give you a general answer for this, since there are a lot of different cases of error handling and so there are a lot of different approaches to deal with this problem. If you would post some real-world examples, you probably would get a lot of suggestions here on SO how to improve your code.

In general, adding error handling to existing functions makes them bigger, so refactoring them up into smaller methods is always a good idea. If you are looking for a more general approach, you should make yourself comfortable with Aspect-Oriented programming. That is an approach to keep out the code for so-called cross cutting concerns (like error handling) completely out of your business logic code.

EDIT: Just one simple trick:

I avoid writing error-checks like this:

 int MyFunction()
 {
    if( ErrorCheck1Passes())
    {
       if( ErrorCheck2Passes())
       {
           if( ErrorCheck3Passes())
           {
                callSomeFunction(...);
           }
           else
              return failureCode3;
        }
        else
           return failureCode2;
    }
    else
       return failureCode1;

    return 0;
 }

I prefer

int MyFunction()
{
   if( !ErrorCheck1Passes())
       return failureCode1;
   if( !ErrorCheck2Passes())
       return failureCode2;
   if( !ErrorCheck3Passes())
       return failureCode3;

   callSomeFunction(...);
   return 0;
}
Doc Brown
+1  A: 

I often wrap up chunks of code that require error handling into their own functions that will handle all possible exceptions internally, and so in a sense always succeed. The code that calls them looks cleaner, and if those functions are called more than once, then your code also becomes smaller.

This can make more sense if you are working more at the front end of an application, where from the user's point of view not every single possible exception needs to bubble up to their level. It's fine in the context of some classes for there to be a robust internal way of handling errors and moving on.

So for example, I might have functions like

SaveSettingsSafe();
// 'Safe' in the sense that all errors are handled internally before returning
Detmar
Good idea about the ...Safe terminology. Will try to use that in my code. (Reminds me of the excellent Joel On Software article about Hungarian Notation: http://www.joelonsoftware.com/articles/Wrong.html)
Rabarberski
+1  A: 

You have rediscovered a major reason that Don Knuth invented literate programming: it is all too common for error handling to obscure the main algorithm. If you're lucky, you'll have some language constructs that offer you some flexibility. For example, exceptions may let you move the error handling elsewhere, or first-class functions may make it possible to move error handling around and reduce if-then-else checks to a function call.

If you're stuck in a language without these features, like C, you might want to look into a literate-programming tool. Literate-programming tools are preprocessors, but their whole mission is to help you make your code more readable. They have a small but rabid following, and you'll be able to find some guidance on the web and in published papers.

Norman Ramsey
Didn't know about literate programming, interesting. Thanks for mentioning it. Although I have my doubts whether it really works in 'the real world'.
Rabarberski