3
\$\begingroup\$

There is a recommendation not to use an Exception to control the flow of execution. This gives me a reason for doubt when I do something like this:

 public void initApplication(String input) {
        try {
            MyClass mClass = new mClass(input);
            saveToDatabase(mClass);
            updateSettingsTheAppIsReady();
        } catch (CancelPreparationsException e) {
            showErrorMessageToUser();
            doRollbacks();
        }
    }

mClass instantiation, save operation to a database, settings update may go wrong, each of them throw their own exceptions, which I catch within the methods/classes and throw my custom exception to stop the initApplication() method execution.

This sounds an easier way than having preconditions checking like:

  1. Create MyClass object.
  2. Check the MyClass object is created then save it to db.
  3. Ensure the object was saved in db then update settings.

Is it really not recommended way of using the Exception to control the flow? Thank you.

\$\endgroup\$
  • 3
    \$\begingroup\$ You're not supposed to use Exceptions for "normal" control flow, f.e. iterating over collections, you only should use it for exceptional cases. If your insert into that database should work 99.99999% of the time (and only because of circumstances beyond your control), then throwing an exception is the right thing to do. If I'm allowed to (and you haven't already read it), I'd like to refer you to "Effective Java, Chapter 9: Exceptions, Item 57: Use exceptions only for exceptional conditions". Joshua Bloch does a way better job at explaining what is meant then I do. \$\endgroup\$ – Bobby Jan 15 '14 at 14:03
6
\$\begingroup\$

I would say that this isn't controlling the flow of your application. This is handling an exceptional circumstance (i.e., failure of your code to perform what as it's meant to), which is what Exceptions are meant to accommodate.

The recommendation is more for circumstances like this:

public boolean itemExists(List<MyObject> list, MyObject object) {
    try {
        for(MyObject thisOne : list) {
            if(thisOne.getAttribute() == object.getAttribute()) {
                throw new Exception("found it");
            }
        }
    }
    catch(Exception e) {
        if(e.getMessage().equals("found it")) {
            return true;
        }
        throw e;
    }
    return false;
}

This controls the flow of the program based on normal execution. It should be pretty easy to see why this isn't ideal, simply for code readability, not considering aspects like performance, style, and best practices.

What you have in the above code is fine. Throwing Exceptions for errors is what they're for. If you're throwing Exception simply to break out of loops or functions or are using them during the "intended" execution of your code, that's when you're going down the wrong path.

\$\endgroup\$
  • \$\begingroup\$ He is certainly not controlling the flow. What he's doing is just error-handling. \$\endgroup\$ – Max Jan 15 '14 at 15:45
  • 2
    \$\begingroup\$ Wait, this is a thing that people do? That's absolutely insane. Anyone who thinks that I good idea needs to be kept away from computer for a long, long time. \$\endgroup\$ – MikeTheLiar Jan 15 '14 at 18:31
  • \$\begingroup\$ @mikeTheLiar Haha, maybe not this simple, but I do see scenarios kind of like this in my production environment. Often. Yay for outsourcing programming labor. \$\endgroup\$ – asteri Jan 15 '14 at 18:43
  • \$\begingroup\$ @Jeff that's TDWTF material right there. \$\endgroup\$ – MikeTheLiar Jan 15 '14 at 18:48
  • 1
    \$\begingroup\$ @Jeff ...and I just found it in our code base. That sound you hear is me slamming my head into my desk. \$\endgroup\$ – MikeTheLiar Jan 16 '14 at 21:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.