Validate User Input, Not Developer Input
I have a very simple rule, I like to follow that helps to simplify my code.
“Don’t validate developer input”
This rule simply means that we should not try and validate input that came from a source that is not a user or external system.
Another way to put it would be, don’t validate parameters you pass around in your own code.
While you can’t guarantee input from another source is valid, you can know that your own code’s input is valid.
When writing a method, we should really strive to know who is calling that method and put the onus on the caller of the method not to pass in junk.
I know this isn’t a popular opinion, because it seems to go against the idea of “defensive programming,” but the idea of defensive programming is misunderstood.
Chuck Norris himself once said:
They say the best defense is not to offend.
That slogan applies well here. Your strategy should be to make sure you always pass valid values into methods rather than trying to code methods to defensively do things with bad input.
(Let’s not be uncivilized!)
Let me give you an example:
Doesn’t that code look silly?
This is the exact opposite of what I am suggesting.
Rather than trying to decide which of these checks we should keep, and trying to follow some complex set of rules of when should we validate input like this, I am merely suggesting we get rid of all of it!
I’ve written about not checking nulls before, but I am convinced now that checking any input from code you control is a code smell.
What can you do?
Throw an exception at best, at worst, infer what was meant by the caller and corrupt data.
What purpose does throwing an exception there serve? If you try and dereference a null object, you get an exception anyway.
Are you even going to catch an exception if you throw it?
If so, does that mean you are wrapping every method call you make in a try / catch block?
The big problem with trying to validate input that was passed to you by code you control is that you can’t really do anything useful. You are just cluttering up your code.
Another question, if you are still gung-ho on validating input on all method calls… Do you even do it?
Do you actually check every parameter, or just when you remember. Because, if you aren’t applying the checks uniformly, you cannot count on them.
One major reason why I advocate validating what you pass into a method rather than what is passed into a method, is context.
If you are inside a method and someone passes you a null, you have no context.
What was going on that cause this parameter to be null? I don’t know—I can’t know!
But—on the other hand, if I am about to call a method and I am about to pass that method a null, I know why. I know that the list I got back was null and I could check for that and instead pass in an empty list to the method I was about to call.
Better yet, I can take it one more step further and not ever pass null back from the method that returns the list in the first place.
The point is that you have way more context before you call the method, than you do when you are in the method. If you are going to validate the input, do it in a place where context will allow you to do something meaningful, rather than just throwing a random exception.
Thinking this way will force you to write better code. I firmly believe it.
Most of us don’t really think about what we are passing into methods or whether or we are returning nulls from methods, we instead tend to think about what we are being passed.
By changing things around, it leads us into better coding practices that are less error prone.
We are forced to think about standardizing and restricting ranges of values for parameters.
We are forced to start considering making our objects immutable, so that if we properly initialize them, they cannot contain null values.
Most importantly, our code becomes cleaner, because it isn’t littered with error checking. Instead of checking for errors everywhere, we are coding in a way that prevents them from being possible.
So the next time you are thinking about validating parameters passed into your method, by another method you have control over, don’t do it!
If you can’t trust yourself, who can you trust? (Chuck Norris perhaps?)