2
\$\begingroup\$

This code is for continuing the execution after an exception, and this is ugly:

    int step=0;

    do{
        try{  
                switch(step)
                {
                case 0:
                    step=1;
                    methodAAAAACanThrowException();
                    break;
                case 1:
                    step=2;
                    methodBBBBBCanThrowException();
                    break;
                case 2:
                    step=3;
                    methodCCCCCanThrowException();
                    break;
                    //....

                    //more and more

                    //....
                case 25:
                    step=26;
                    methodZZZZZCanThrowException();                        
                }                      
        }catch( Exception ex)
        {  

            Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, null, ex);
        }
    }while(step<26);
}

but writing a single try-catch loop for every call, seems even uglier..

Is there any other more elegant option for doing that? thanks

\$\endgroup\$
  • 2
    \$\begingroup\$ The fact that you want do this is a bad sign. Why do you want to do this? What kind of function is this? What kind of methods is it calling? Chances are a better way to design your solution exists. \$\endgroup\$ – Winston Ewert Jan 23 '12 at 18:41
6
\$\begingroup\$

How about something like this?

Define a one-method interface like so:

public interface TryAndLogFailure { void execute(); }

Then define a method which takes an object which implements the interface and does your exception handling for you:

public void tryAndLogFailure(TryAndLogFailure talf) {
  try {
    talf.execute();
  } catch (Exception e) {
    logger.log(...);
  }
}

Now your calls to the methods can be sequential:

tryAndLogFailure(new TryAndLogFailure{ public void execute() { methodAAAACanThrowException(); } });
tryAndLogFailure(new TryAndLogFailure{ public void execute() { methodBBBBCanThrowException(); } });
// etc...
tryAndLogFailure(new TryAndLogFailure{ public void execute() { methodZZZZCanThrowException(); } });

Admittedly, this could probably be worked a little more to make it prettier, but this is my first crack off the top of my head. If only Java had support for closures.

(Also - I should note that I agree with Winston. The reason why this code feels ugly is because the concept itself is ugly. Catching Exception is almost never a good idea and requires strong justification. Given more context, we may be able to help you redesign the code to avoid this sort of code smell.)

\$\endgroup\$
  • 1
    \$\begingroup\$ Hello @mike9322, +1 for the answer, catching Exception is not the central point about this issue, I have post a similar question in stackoverflow, I think this is a Java debt, as you mention perhaps closures, I don't know, but is very messy to "retry" or continue the call of consecutive methods when some of them throws an exception, here is a better description of the general issue, stackoverflow.com/questions/2700173/… this is my first post here, just to read different opinions, thanks \$\endgroup\$ – Hernán Eche Jan 24 '12 at 17:27
  • 1
    \$\begingroup\$ This might be technically sound but it hurts my eyes and brain. Having to do this is just another reason why Java needs lambda. tryandLogFailure(() => methodAAAACanThrowException()); would of been perfect. \$\endgroup\$ – Andrew T Finnell Jan 26 '12 at 22:09
4
\$\begingroup\$

It doesn't have to be as complicated as the other answers. And there are valid reasons for logging and continuing execution of a method.

It appears you are using the execution of the steps to advance to the next step regardless of exceptions. So it seems better to use a for loop.

I'm not really liking the use of switch statements to execute methods in order, but I think fixing that might go beyond the original intent of this question. Too bad Java doesn't have native lambda.

// Execute all steps regardless of exceptions
void executeAllSteps() {
    for (int step = 0; step < 26; ++step) {
        try {
            executeStep(step);
        } catch (Exception ex) {
             // Collect the exception in a list or add it to 
             // a log file.
        }
    }
}

void executeStep (int step) throws Exception {
    switch(step) {
        case 0:
            methodAAAAACanThrowException();
            break;
        case 1:
            methodBBBBBCanThrowException();
            break;
        case 2:
            methodCCCCCanThrowException();
            break;
        case 25:
            methodZZZZZCanThrowException();   
            break;                     
    }
}
\$\endgroup\$
0
\$\begingroup\$

The combination of do and switch is pointless. It's doing the same thing as simply calling each method sequentially and nothing more.

Just put those calls inside a try block.

try {
    methodAAAAACanThrowException();
    methodBBBBBCanThrowException();

}catch(Exception e) {
    Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, null, ex);
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Wrong, that won't work, if methodAAAAACanThrowException(); throw an Exception then methodBBBBBCanThrowException(); won't be executed \$\endgroup\$ – Hernán Eche Jan 24 '12 at 17:16
  • \$\begingroup\$ Uh, ok. I'll leave it here so everyone will know what not to do. \$\endgroup\$ – radarbob Apr 13 '12 at 16:11

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.