User Input Validation – How to Handle Invalid Input

user-interactionvalidation

I have been thinking about this issue for a while and I would be curious to have opinions from other developers.

I tend to have a very defensive style of programming. My typical block or method looks like this:

T foo(par1, par2, par3, ...)
{
    // Check that all parameters are correct, return undefined (null)
    // or throw exception if this is not the case.

    // Compute and (possibly) return result.
}

Also, during the computation, I check all pointers before dereferencing them. My idea is that, if there is some bug and some NULL pointer should appear somewhere, my program should handle this nicely and simply refuse to continue the computation. Of course it can notify of the problem with an error message in the log or some other mechanism.

To put it in a more abstract way, my approach is

if all input is OK --> compute result
else               --> do not compute result, notify problem

Other developers, among them some colleagues of mine, use another strategy. E.g., they do not check pointers. They assume that a piece of code should be given correct input and it should not be responsible for what happens if the input is wrong. Also, if a NULL pointer exception crashes the program, a bug will be found more easily during testing and have more chances of being fixed.

My answer to this is normally: but what if the bug is not found during testing and appears when the product is already being used by the customer? What is a preferred way for the bug to manifest itself? Should it be a program that does not perform a certain action, but can still continue to work, or a program that crashes and needs to be restarted?

Summarizing

Which of the two approaches to handling wrong input would you advise?

Inconsistent input --> no action + notification

or

Inconsistent input --> undefined behaviour or crash

Edit

Thanks for the answers and suggestions.
I am a fan of design by contract too. But even if I trust the person who has written the code calling my methods (maybe it is myself), there can still be bugs, leading to wrong input. So my approach is to never assume a method is passed correct input.

Also, I would use a mechanism to catch the problem and notify about it. On a development system, it would e.g. open a dialog to notify the user. In a production system it would just write some information to the log. I do not think that extra checks can lead to performance problems. I am not sure if assertions are enough, if they are switched off in a production system: maybe some situation will occur in production that had not occured during testing.

Anyway, I was really surprised that many people follow the opposite approach: they let the application crash "on-purpose" because they maintain that this will make it easier to find bugs during testing.

Best Answer

You've got it right. Be paranoid. Don't trust other code, even if it's your own code. You forget things, you make changes, code evolves. Don't trust outside code.

A good point was made above: what if the inputs are invalid but the program does not crash? Then you get garbage in the database and errors down the line.

When asked for a number (e.g. price in dollars or number of units) I like to enter "1e9" and see what the code does. It can happen.

Four decades ago, getting my B.S. in Computer Science from U.C.Berkeley, we were told that a good program is 50% error handling. Be paranoid.

Related Topic