CowZow
CowZow

Reputation: 1414

Embedding try-catch blocks within try-catch blocks in Java

Let's say I have method a() and method b() which both may throw an exception. In my program, there is a situation where I have to call at least one of them; it doesn't matter which I call. However, if one of them throws an exception, I have to call the other one. If they both throw an exception, I don't have to do anything.

I was thinking of doing something like this:

try {
    a();
catch (Exception e) {
    try {
        b();
    catch (Exception e) {

    }
}

but I thought this would be impractical if I had more than two methods to call. So I was wondering if there were a more elegant or better way to do something I'm trying to do.

Upvotes: 1

Views: 1983

Answers (3)

Stephen C
Stephen C

Reputation: 718926

It is difficult to discuss practical options at such a level of generality, but you could do something like this:

boolean succeeded = false;
try {
    a();
    succeeded = true;
} catch (Exception e) {
    // intentional ...
}
if (not succeeded) {
    try {
        b();
    catch (Exception e) {
        ...
    }
}

... and all sort of other arrangements where you use conditionals (or break or return) to avoid the nesting.

But whether they are more "elegant" ... or more readable ... will be highly context dependent. And also dependent on the reader. (As an experienced Java programmer, I have no difficulty understanding nested exceptions. In my experience, artificial constructions that are intended to avoid nesting can result in code that is harder to read / understand.)


I hope that you are not really going to catch Exception ... 'cos if you are, that is a much worse problem than than nesting of try / catch!!

Upvotes: 0

irreputable
irreputable

Reputation: 45443

you can

    abc:
    {
        try
        {
            a();
            break abc;
        }
        catch(Exception e){}

        try
        {
            b();
            break abc;
        }
        catch(Exception e){}

        try
        {
            c();
            break abc;
        }
        catch(Exception e){}

    }

if the chain is even longer, probably better

for(int i=0; i<4; i++)
{
    try 
    {
        switch(i)
        {
            case 0: a(); break;
            case 1: b(); break;
            case 2: c(); break;
            case 3: d(); break;
        }
    }
    catch(Exception e){} // next
}

Upvotes: 2

Eric
Eric

Reputation: 97601

You can return after each case, such that after the first success, a return is hit.

public void uponSuccessStop() {
    try {
        a();
        return;
    } catch (Exception e) {}
    try {
        b();
        return;
    } catch (Exception e) {}
    try {
        c();
        return;
    } catch (Exception e) {}
}

Another option would be to throw out exceptions, and use short-circuit boolean logic:

public boolean tryA() {
    try {
        a();
        return true;
    } catch (Exception e) {
        return false;
    }
}
// repeat for B and C

public void uponSuccessStop() {
    boolean succeeded = tryA() || tryB() || tryC();
}

Upvotes: 2

Related Questions