André André - 3 months ago 7
Java Question

Should exceptions be used to unwinding process back to main?

Now this is really quite difficult for me to explain so please bear with me.

I've been wondering as of late the best way to "unwind" every chained method back to a main method when certain circumstances are met. For example, say I make a call to a method from Main and from that method I call another one and so on. At some point I may want to cancel all further operations of every method that is chained and simply return to the Main method. What is the best way to do this?

I'll give a scenario:

In the following code there are 3 methods, however when Method1 calls Method2 with a null value it should unwind all the way back to Main without further operations in Method2 (EG the "Lots of other code" section).

public static void main(String[] args)
{
try
{
Method1();
}
catch( ReturnToMainException e )
{
// Handle return \\
}
}

public static void Method1() throws ReturnToMainException
{
String someString = null;
Method2( someString );

// Lots more code after here
}

public static boolean Method2( String someString )
{
if( someString == null )
throw new ReturnToMainException();
else if( someString.equals( "Correct" ))
return true;
else
return false;
}


In this example I use a throw which I've read should only be used in "Exceptional Circumstances". I often run into this issue and find myself simply doing If/Else statements to solve the issue, but when dealing with methods that can only return True/False I find I don't have enough options to return to decide on an action. I guess I could use Enumerators or classes but that seems somewhat cumbersome.

Answer

I use a throw which I've read should only be used in "Exceptional Circumstances". I often run into this issue and find myself simply doing If/Else statements to solve the issue

Exception throwing is relatively expensive so it should not be used without careful thought but I believe that your example is a ok example of proper usage.

In general, you should use exceptions only for "exceptional" behavior of the program. If someString can be null through some sort of user input, database values, or other normal mechanism then typically you should handle that case with normal return mechanisms if possible.

In your case, you could return a Boolean object (not a primitive) and return null if someString is null.

private static Boolean method2( String someString ) {
     if (someString == null) {
         return null;
     }
     ...
}

Then you would handle the null appropriately in the caller maybe returning a boolean to main based on whether or not the method "worked".

private static boolean method1() {
    ...
    Boolean result = method2(someString);
    if (result == null) {
        // the method didn't "work"
        return false;
    }

Then in main you can see if method1 "worked":

public static void main(String[] args) {
    if (!method1()) {
        // handle error
    }
    ...
}

Notice that I downcased your method names and changed the permissions of your methods to private both which are good patterns.

Enumerators or classes but that seems somewhat cumbersome.

Yeah indeed. It depends a bit on how this code is used. If it is a API method that is called by others, you might want to return some sort of Result class which might provide feedback like a boolean that the argument was null. Or you might throw an IllegalArgumentException in that case. Instead, if this is an internal local private method, then I'd vote for a simpler way of handling argument errors. Either way I'd use javadocs to document the behavior so you don't trip up future you.

Hope this helps.

Comments