Custom exceptions or empty list - java

I am working on a project to parse the text. I am parsing for specific text and store them in the array. I have written a class for it. If I get improper text so that I cannot find what I want in the given input, What is the best practice, should I return the empty array and let the calling class handle it or should I raise a custom exception to the calling class.

If I were using your class as a library and received an empty array as a return value, I would assume -- barring documentation otherwise -- nothing had been read (and be very confused if my input had text to read!)
Similarly, I would hope that when and if a piece of library code threw an exception, it would throw something useful so that I could debug the problem. That might come in the form of a custom exception, or it might come in the form of an existing library exception; for example, ParseException, which supplies the offset into the text where the exception occurred. However, if there is some other piece of information that's relevant to your particular exceptional case, then a custom Exception subclass may be warranted.

If caller's view of empty-list is error i.e. caller always except some value in list and handling empty list is not usual in his case that's a signal that a custom exception is better.
For example: If caller has a category input and contract is your API will have its product, emptiness is error according to contract.
Now, if there is no use-case of above tight contract between caller and API, it's perfectly valid to send empty list.
For example: Caller asks for a list of XYZ articles and you don't have, an empty article list is fine.
It's purely subjective and use-case driven, Java doesn't provide any specific guidelines on this.

It's hard to have "best practices" since every design case is different. As a rule of thumb, consider what API would be easiest for your consumer to use and would be least surprising. I also highly suggest picking up a copy of Effective Java by Joshua Bloch if you haven't seen it already. Specifically applicable are sections on "Use Exceptions for Exceptional Conditions", and "Favor use of the Built in Exceptions" (and the book contains lots of other good style and correctness suggestions).
Now to your particular case:
Is it expected that your user should provide proper text or improper text as input? If the former, then an Exception is more likely the correct solution. Furthermore, If you returned an empty array, What would the difference be between proper text that happens to be empty, and improper text? Could you tell the difference in your calling code? Does such a distinction matter?
Now what exception to throw? You could throw a subclass of IOException (as you're dealing with input), the (arguably) potential downside is that IOException is not a RuntimeException so anyone calling your code would be forced to either handle the exception or rethrow it. (Checked versus Unchecked exceptions is another debate).

It depends on what you are doing. If improper text is a common and expected thing, simply ignoring it and returning an empty array (or null) may be completely reasonable. But if improper text should never happen and calls into question the validity of previously or subsequently processed input (that may already have been added to the array) you should probably throw an exception.

Related

Should I throw checked or unchecked exception for invalid input? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
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,
Is the defensive programming justified here?
If so, should it throw a checked or unchecked exception?
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.
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
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.
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".

When to throw IllegalStateException vs IllegalArgumentException?

Let's start with the Javadocs:
IllegalStateException
Signals that a method has been invoked at an illegal or inappropriate
time. In other words, the Java environment or Java application is not
in an appropriate state for the requested operation.
IllegalArgumentException
Thrown to indicate that a method has been passed an illegal or
inappropriate argument.
The problem with the above is that they are very black and white. Consider a use case where a method is parsing a file provided by the caller. The file exists, is readable, and is in the correct format. However, some content in the file is non-compliant with the business rules. What would be an appropriate exception to throw in this case - IllegalStateException or IllegalArgumentException?
Looking at various libraries that provide assertions, like Guava Preconditions or Spring Assert, it appears that there is no consensus. There are some good discussions here and here, but none provide a conclusive answer to the common use case I stated above.
Putting in other words:
The IllegalArgumentException is thrown in cases where the type is accepted but not the value, like expecting positive numbers and you give negative numbers.
The IllegalStateException is thrown when a method is called when it shouldn't, like calling a method from a dead thread.
I don't see how they could mix. In your question about the file with problems, I think that throwing either a ParseException or an IOException would be more appropriate.
IllegalStateException is for coding errors, not input errors. It's for when the invariants of a class have been violated, or a method is called when an object is in the wrong state. Examples are using a closed resource, or closing a resource twice.
IllegalArgumentException is when an argument has an invalid value per the method API. Passing -1 when only positive numbers are allowed.
In this case neither exception is appropriate. I would create a sub-class of IOException since there's an error in an input file.
The other answers highlight when to use IllegalArgumentException or IllegalStateException. But in my view (note: opinion based) these exceptions should not be used in your use case.
To summarize: Some file contains data in a valid format, is successfully loaded into the application but some values are not compliant to your business rules (Note: No IO operations failed, the format is valid => neither IOException nor ParseException should be used, they indicate failed IO operations or invalid formats).
Why you should not use IllegalArgumentException?
This exception is thrown to indicate that a method has been passed an illegal or inappropriate argument. You could argue that you have a method validating the file and the value of a field or the combinations of values of several fields in this file are illegal or non-compliant to your business rules. Yepp, point to you. But if you throw an IllegalArgumentException in this situation you can not separate IllegalArgumentExceptions caused by other libraries (or the standard library or from your own code somewhere else) and the IllegalArgumentExceptions from your validator which indicate a business rule violation easily (sure, you could subclass IAE and catch it in a calling method).
Why do you want to separate these exceptions? Use case: Business rule violations should be presented to the user so he can change his non-compliant inputs. Other IAE's or general any uncatched runtime exception indicates that the request failed on the server for example. In these cases you have to send different responses to clients.
You can argue in a similar way why IllegalStateExceptions should not be used to indicate business rule violations. So, what should be used in your use case?
This depends highly on the scale of your application. Some custom subclass of RuntimeException may do the Job for small applications. For larger applications validation libraries like "javax.validation" are worth a try.
I also think that the two methods have a very close semantic.
According to the IllegalArgumentException javadoc, passing an invalid argument may be handled by throwing IllegalArgumentException :
Thrown to indicate that a method has been passed an illegal or
inappropriate argument.
But invoking a method with a bad argument may also be handled by throwing IllegalStateException as its javadoc states that :
Signals that a method has been invoked at an illegal or inappropriate
time.
Indeed, invoking a method with an inappropriate or illegal argument may also mean that the method was invoked at an illegal or inappropriate time.
To make simple, I think that IllegalArgumentException and IllegalStateException may be used in a interchangeable way by some developers as the issue is caused by the passed argument(s). What I explained above.
While IllegalStateException use cases that are not related to a passed argument have not to be interchanged with IllegalArgumentException.
The nuance being slight, most of libraries mix sometimes their usage.
I am afraid to not be able to give you a more solid explanation.
Semantic is semantic and as two things may be interpreted in a closer way, it is often not clearly used.
Consider a use case where...
And if those were the only two options I had, in your use-case, I'd lean towards IllegalStateException
Why? Because the argument's are valid, they point to a file, which can be read. It's not the argument that is invalid, it's the fact that parsing the file would invalid the state.
This of course assumes that IllegalStateException and IllegalArgumentException are the only exceptions you are considering.
This is course just MHO. I think the important aspect is, you can define the reasons for using one exception over another in a consistent way which makes your API understandable.
I also agree with Saclyr (+1 to their answer), there are more appropriate exceptions you could use to define why the method call failed (personally, I'd consider java.text.ParserException)

Are exception flow control better in certain scenarios?

There are many articles explaining why exception flow control should be avoided and is considered an anti-pattern. However, does using exception flow control makes sense in following example?
Eg: I have an enum type with many values and need to check if it contains a given string.
The solution using Enum.valueof shall throw an IllegalArgumentException and can be used to return false. Even Apache commons lang3 lib uses same. We reuse one time lazy initialized enumConstantDirectory map on all subsequent calls.
return EnumUtils.isValidEnum(MyEnum.class, myValue);
Other solution would be to iterate.
return Stream.of(MyEnum.values()).anyMatch(e -> e.name().equals(value));
Programming is always about balancing between "informal standards" and deviating from rules where it makes sense.
Yes, Java is one of those languages where you "look before you leap" (you check conditions); not like Python where you "ask for forgiveness" (not for permission).
In other words: most of the time, a Java programmer would find it surprising to look at code that uses exceptions for control flows. But: that doesn't mean that one never should work this way.
My personal two cent here: I think you should rely on exceptions when that case indicates a real exceptional condition in your program. Meaning: when those strings you are checking are supposed to represent enum constants ... than an exception might be fine. But when there is a certain chance (and maybe even "valid" reasons) at runtime that a string is invalid, then I would rather use a method that goes boolean isValid() and not throw an exception.

Clear and simple rules for deciding between checked and unchecked exceptions

Since there is a lot of ambiguity about this, can we come up with some clear, simple and easy to use rules?
Here is a first try, these three rules should be sufficient for all cases.
First rule is based on the common principle that implementation details of the method should not be exposed to the caller:
Rule 1:
Checked exception should not expose implementation details to the caller:
You can test it this way: If you completely change the implementation but still expect the method to fulfill its contract (like in refactoring) would it still make sense to throw the exception?
If yes then it should be a Checked exception because it is not implementation detail but part of use case the method fullfills.
If no then the exception should be unchecked because it is an implementation detail which should not be exposed to the caller.
If based on Rule 1 the exception should be checked then apply the Rule 2:
Rule 2: Since checked exception is part of the method contract, violation of the method's contract can't be a checked exception.
For example this method executes sql query from its param:
executeSqlQuery(String sqlQuery)
If caller provides string that is not an sql query then he violated input conditions of the method and the resulting exception must be unchecked.
If based on Rule 2 the exception still seems like checked, apply rule three which checks whether the method is following another best practice: single responsibility principle
Rule 3: Method should do just one thing.
For example method
List.get(int index)
is correctly doing just one thing: returning desired element from the list. And not trying to also fulfill another common use cases: check whether the element is present.
On the other hand method
findById(Long id) throws RecordNotFoundException
is incorrectly trying to mix these two functions and by that forces all callers to always consider the use case when record is not found even though they know that the record exists.
Is some rule missing or can we simplify and clarify the rules further?
BACKGROUND:
There are many different views on this topic. There is quite a lot of proponents of "radical" solutions like never to use a checked exception (some java books or designers of C#) or that almost everything should be a checked exception (IOException in java.io package or SQLException in JDBC).
And at least same number of views suggest to use both types but are offering subjective and ambiguous rules for deciding between them which without a lengthy explanation that is often missing instead of helping just bring more confusion (eg: If it is reasonable for the caller to recover from the exception than it should be checked. Is trying the call again a reasonable recovery? For some clients it may be. Words reasonable and recover are too ambiguous.)
Um, that question is answered in the official Java Tutorials, in fact:
Here's the bottom line guideline: If a client can reasonably be expected to recover from an exception, make it a checked exception. If a client cannot do anything to recover from the exception, make it an unchecked exception.
That looks like a pretty clear, simple rule to me.
EDIT: your background edit explains your confusion and frustration quite well. If you want to, I can come up with a even simpler rule:
Always be usable. Try to be practical where possible. Strive to be consistent.
The point is that exception handling is something that the user of the method that might throw must do. Sadly, Java forces the person who writes that method to make the choice for the user of that method. Thus, I'm leaning slightly towards the "never do checked" side, because your methods will always be usable. For some cases, for example network I/O, it might be really practical to force the user to build in some error handling, but that's not really often the case. If you're asking yourself hm, my last 400 methods all threw RuntimeErrors, should this now throw a checked exception?, attaining consistence might make using your library more practical.
Sadly, this rule is easier, but not clearer, because at least practical and consistent are very subjective notions. So here you are, stuck with something that is really a question of style.
The fundamental problem with the way Java handles checked exceptions is that while it would be useful to distinguish exceptions that get thrown for expected reasons (e.g. getRecordById throwing a RecordNotFoundException when given an ID that doesn't exist) from those which get thrown for unexpected reasons (e.g. a method which calls getRecordId for an ID which is supposed to exist, but doesn't), the type of an exception has little to do with whether it's coming from a method for reasons that method knows about, or because it was unexpectedly thrown in a nested method call.
If Java allowed exception instances to be marked as "expected" or "unexpected", with distinct statements for catching expected and unexpected ones as well as a means of indicating that any methods within a block aren't expected to throw certain exceptions (and if any such exceptions that are thrown are marked as "expected", they should be flagged "unexpected" before propagating out) then having certain methods declared as throwing "expected" exceptions would be useful. Given the present architecture, however, it's better to simply declare most exceptions as being unchecked.

How should I return a value from function?

Three ways I see here:
1) make function return that value explicitly
2) add additional argument to the function's argument list and pass string holder as that parameter. After the function completes its execution, that string holder will contain the result of the function.
3) throw an exception from that function that will contain the result.
I for myself see first choice more preferable because it's simple, intuitive and straight.
On the other hand, when execution of the function goes in a wrong way there may be additional choices like throw an exception or use a variable passed through parameter to save errors if any happen.
Intuitively, I see that ideal choice is to have explicit return value and throws declaration. So return value is used for normal execution and caught exception will signal about abnormal situation. But I myself don't like exceptions too much if only it is not the completely unpredictable error, so I'd use explicit return value and additional parameter to hold some extra-situation logs or errors.
Please advise books or articles on the subject (it shouldn't necessary talk about Java, any other languages with similar mechanisms are also suitable).
You absolutely want option #1. Exceptions are not unpredictable; if you use them correctly, they are in fact entirely predictable. You can throw different exception types based on the error (FileNotFoundException, IllegalArgumentException, SomeConditionSpecificToMyAppException, etc), and those exceptions can contain any error or diagnostic information you need to convey.
Here's a good section in the Java SE tutorial on exceptions: http://docs.oracle.com/javase/tutorial/essential/exceptions/
Java methods have return values for a reason: to return their results. In the vast majority of cases #1 should be your only choice. Even if you want to return a wrapper object e.g. because you need to return multiple values, you should probably just return the thing...
Exceptions are just that: they are thrown in exceptional (i.e. abnormal) circumstances. Since traditionally throwing an exception also implies a performance impact, exceptions should not be thrown during normal operation.
Why are you trying to confuse yourself?
EDIT:
On the other hand, exceptions are quite suitable for rare/abnormal conditions:
They have built-in support for the generation of debugging information. Getting a stack trace is half the battle in dealing with most bugs.
All decent debuggers allow for thrown exceptions to be used as a break point, which can be invaluable.
Exceptions allow for error conditions to be passed up the method call chain relatively transparently, allowing for the error handling code to be placed with as much granularity as desired.
Exceptions are the standard way to deal with error conditions in Java. This should be enough for most programmers. Please respect the people that will have to work with your code and don't break such basic conventions by reinventing the wheel...
I would use choice 1 almost every time. There is nothing stopping you throwing a Exception as required.
Please read Code Complete by Steve McConnell. It's all there.

Categories