I inherited a java application that processes requests and throws an exception if it determines a request should be cancelled. Exceptions have been convenient for the previous developer because they are an easy way to exit out of a tree of logic that no longer applies (yes a goto) and it prints a stack trace to the log which is good info to have. It seems to be the consenus on forums and blogs that exceptions should not be used for flow control and over half of the requests processed are cancelled, so they're definitely not exceptional situations. One argument is performance, which doesn't apply because our exception-ful code has run fast enough for years. Another argument is that the goto-ness of it is not clear, which I agree with. My question is: What is the alternative. The only thing I can think of is to have every method return true if processing should continue or false if it shouldn't. This seems like it would hugely bloat my code changing this:
checkSomething();
checkSomethingElse();
into this:
boolean continueProcessing = false;
continueProcessing = checkSomething();
if (!continueProcessing) {
return false;
}
continueProcessing = checkSomethingElse();
if (!continueProcessing) {
return false;
}
And then what if the method is supposed to return something? Any guidance would be great. I'd really like to observe whatever "best practices" are available.
Update:
Another bit I probably should have mentioned in the first place is that a request is cancelled more than 50% of the time and does not mean something didn't go right, it means the request wasn't needed after all.
According to many references like here and here, using Exceptions to control application flow is an anti-pattern that is not recommended. (Because of performance issues, Less readable and etc).
Each transition from ak to ak+1 is called a control transfer. A sequence of such control transfers is called the flow of control, or control flow of the processor. The simplest kind of control flow is a “smooth” sequence where each Ik and Ik+1 are adjacent in memory.
In your scenario, the alternatives are throwing an exception and returning a result.
Which is best (and which is "best practice") depends on whether the failure of the "check..." methods should be classed as normal or exceptional. To some degree this is a judgement call that you have to make. In making that call there are a couple of things to bear in mind:
Creating + throwing + catching an exception is roughly 3 orders of magnitude SLOWER than testing a boolean result.
The big problem with returning status codes is that it is easy to forget to test them.
In summary, best practice is to not use exceptions to implement normal flow control, but it is up to you to decide where the borderline between normal and exceptional is.
Without seeing the real code / context, my gut feeling is that this is likely to be an appropriate place to use exceptions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With