Should I throw checked or unchecked exception for invalid input?

1.3k views Asked by At

I'm writing a method which expect some input. Now, I thought that it would be a good practice to write it in a defensive way (i.e. checking that the input is correct).

Basically, the input should be okay since there's only one place (reliable) that uses this method.

So my question is,

  1. Is the defensive programming justified here?
  2. If so, should it throw a checked or unchecked exception?
4

There are 4 answers

0
ygor On BEST ANSWER

Basically, the input should be okay since there's only one place (reliable) that uses this method.

It's great, that you reason about your function this way. You just defined a contract for your function. It says, that this function expects a valid input. In this case, it is a very good practice to employ defensive programming by throwing an exception when invalid input is detected. This exception will greatly simplify detection of callers of your function, who broke contract and called your function with invalid input.

If you did not throw a dedicated exception, than (if you are lucky) your function might break by throwing a generic technical exception, e.g. NullPointerException or perhaps ArrayIndexOutOfBoundsException. Such stacktrace still shows, that something wrong happened, when your function was called. However, you need to analyze, "what" happened. In worst case, your function would not throw any exception at all and "somehow" process invalid input. Your program than can later break on seemingly unrelated location or in even worse case, it does not break and it presents wrong result to the user.

Is the defensive programming justified here?

Yes, it definitely is.

If so, should it throw a checked or unchecked exception?

Checked vs unchecked exceptions is still an ongoing debate. You can find many answers to this question on StackOverflow. Scala language only has unchecked exceptions. I personally prefer them too.

What if your function expects invalid input too?

Typically, these are functions, which receive input from humans. For example an user registration form requires password, which is not too short and contains at least one digit. In this case, "failure" is expected and should somehow be encoded in function's return value, so that caller of the function is forced to inspect both kinds of return value - Success and Failure. Such return values can be modeled using algebraic data types. Java does not allow to model ADTs naturally and we got used to model Failure by throwing an exception. Maybe in this case checked exceptions still make sense.

Edit:: Other answers go into more details on "when" to validate and when to not. To summarize: public methods - yes; do not repeat same validation across layers.

1
Thiyagu On

Think about what will happen to the rest of the system or application if you did not have that check and some invalid input came in.

Do you have a safe default value to fallback and use? Is it the correct value for all cases? Does the caller/client of your code/API need to be notified of this? So, based on this, you can even just log a warning and can continue using the default value. But in most cases, it will not be the case.

[..] there's only one place (reliable) that uses this method.

It is as of today. In the future, it might change. So, IMO, you can have the check that the input is valid.

should it throw a checked or unchecked exception?

That again takes us back to the callers or clients of your code/API. Do you want them to expect it to happen and handle it? If they can handle the exception and recover, then it makes sense (Note: This means that all the callers need to have a try..catch block when calling your API/code). Else, if they are supposed to pass a valid value and if they don't, an unchecked exception will do (Make this clear in the contract/Javadoc)

Let us look at an example in the Java libraries itself.

Many methods in the File class throw a checked exception.

Integer.valueOf throws an NumberFormatException (which is an unchecked expcetion) if the input is invalid.


A good practice is, any public API must validate its inputs.

Also, have a look at Java: checked vs unchecked exception explanation before deciding

0
Ali Reza Dehdar On

I didn't take your whole question into account, so I will change my answer.

Should you check input?

With public methods - Always. Reason being that best practice is always to call interfaces and not implementations. So when you have an interface, you want anyone using your implementation of it, to get proper feedback if they pass invalid arguments.

Should you throw exceptions?

Yes! As Uncle Bob says it's better to forget to catch an exception than forget to check a return value to check for errors. In other words, exceptions are more fool proof as they don't fail "silently".

0
davidxxx On

Multiplying in an idiomatic way the same input checks in each layer of the call is generally a bad practice : you repeat yourself and changes for it can fast become an hell or a messy.
So I would think that if your method is designed to be an API usable by multiple client classes it should do this check even it may be redundant. Otherwise just stay DRY.

Note that the best way to ensure consistency in your API is covering your methods by unit tests.
In this way you provide the checks only when its functional requirement demands that and you don't overthink.

If so, should it throw a checked or unchecked exception?

Using checked or unchecked exceptions usage is very debatable.
In theory checked exceptions are great when it is required that the client handles it. But in practice it may become noise if the client don't want to handle it or if the method is used inside a lambda body.