einpoklum
einpoklum

Reputation: 131544

How can I keep my thrown exception for the finally block?

I have the following code:

try {
    /* etc. 1 */
} catch (SomeException e) {
    /* etc. 2 */
} catch (SomeException e) {
    /* etc. 3 */
} finally {
    /* 
     * do something which depends on whether any exception was caught,
     * but should only happen if any exception was caught.
     */

    /* 
     * do something which depends on whether an exception was caught and
     * which one it was, but it's essentially the same code for when no
     * exception was caught.
     */
}

So, I want to keep my caught exception. Any way to do this other than assigning to a variable in every catch block?

Edit: Just to clarify, please don't post answers suggesting I use a variable scoped outside the try block. I know I can do that, the whole point of this question is finding an alternative.

Now, what I would really like to have is more flexible catch block, so that multiple catch blocks could catch the same exception, e.g. catch(Exception e) would catch everything even if it was already caught, catch(Exception e) except(NullPointerException, IllegalArgumentException) would skip the excepts. And a catch block could do catchingcontinue; to skip all other catch blocks for the same try block and catchingbreak; to skip even the finally.

Upvotes: 1

Views: 406

Answers (4)

Alepac
Alepac

Reputation: 1831

Try this:

try {
    // your code throwing exceptions
} catch (Exception e) { // This catch any generic Exception
    // do whatever you want to do with generic exception
    ...
    if (e instanceof SomeException) {
        ...
    } else if (e instanceof OtherException) {
        ...
    }
}

using java 7 you can even do this:

try {
    // your code throwing exceptions
} catch (SomeException|OtherException e) { // This catch both SomeException and OtherException
    // do whatever you want to do with generic exception
    ...
    if (e instanceof SomeException) {
        ...
    } else if (e instanceof OtherException) {
        ...
    }
}

Upvotes: 2

sharakan
sharakan

Reputation: 6901

What I would recommend here is that you extract the details of the exception handling out to new methods, and call those methods from catch blocks that are as specific as necessary to avoid instanceof checks. This has the advantage of not using instanceof, keeping exception handling code in catch blocks instead of in finally, and clearly separating shared exception handling code from specific exception handling code. Yes, there's some shared code between the three catch blocks, but it's a single clear line of code, which seems acceptable to me.

try {
    // do work that uses resources and can generate any of several exceptions
} catch (SomeException1 e) {
    standardExceptionHandler(e);
    specificExceptionHandler1(e);
} catch (SomeException2 e) {
    standardExceptionHandler(e);
    specificExceptionHandler2(e);
} catch (Exception e) {
    standardExceptionHandler(e);
} finally {
    // this would include only code that is needed to cleanup resources, which is
    // what finally is supposed to do.
}

Upvotes: 1

Garis M Suero
Garis M Suero

Reputation: 8169

You will need to assign it to a variable outside the try-catch block and use it on the finally block.

Exception caughtException = null;

try {
    /* etc. 1 */
} catch (SomeException e) {
    caughtException= e;
} catch (SomeOtherException e) {
    caughtException= e;
} finally {
    if (caughtException != null) {
        /* 
         * do something which depends on whether any exception was caught,
         * but should only happen if any exception was caught.
         */
    }
}

Looks like you want to do some auditing. Why don't you use some annotations and AOP to handle the behavior, of course with a good exception handling to catch those exceptions on the before or after.

Upvotes: 1

Thihara
Thihara

Reputation: 6969

Keep a variable outside the scope of the catch block and assign it in the catch block.

Buy I strongly recommend that you do not do this.

Finally block should be used for resource cleanup or any similar functionality that need to be run regardless of the exceptions.

All the exception handling should be done in the catch blocks, not the finally blocks.

Upvotes: 1

Related Questions