user18424
user18424

Reputation: 451

What happens when both catch block and finally block throw exception in Java?

Consider this question I was asked in an interview

public class Test_finally {
    private static int run(int input) {
        int result = 0;
        try { 
            result = 3 / input;
        } catch (Exception e) {
            System.out.println("UnsupportedOperationException");
            throw new UnsupportedOperationException("first");
        } finally {
            System.out.println("finally input=" + input);
            if (0 == input) {
                System.out.println("ArithmeticException");
                throw new ArithmeticException("second");
            }
        }

        System.out.println("end of method");
        return result * 2;
    }

    public static void main(String[] args) {
        int output = Test_finally.run(0);
        System.out.println("  output=" + output);
    }
}

Output of this program throws ArithmeticException not UnsupportedOperationException

Interviewer simply asked how will i let the client know the original exception raised was of type UnsupportedOperationException not ArithmeticException. I didn't know that

Upvotes: 3

Views: 924

Answers (1)

k5_
k5_

Reputation: 5558

Never return or throw in a finally block. As an interviewer i would expect that answer.

A crappy interviewer looking for a minor technical detail might expect you know Exception.addSuppressed(). You can not actually read the thrown exception in a finally block so you need to store it in the throw block to reuse it.

So something like that:

private static int run(int input) throws Exception {
    int result = 0;
    Exception thrownException = null;
    try {
        result = 3 / input;
    } catch (Exception e) {
        System.out.println("UnsupportedOperationException");
        thrownException = new UnsupportedOperationException("first");
        throw thrownException;
    } finally {
        try {
            System.out.println("finally input=" + input);
            if (0 == input) {
                System.out.println("ArithmeticException");
                throw new ArithmeticException("second");
            }
        } catch (Exception e) {
            // Depending on what the more important exception is,
            // you could also suppress thrownException and always throw e
            if (thrownException != null){
                thrownException.addSuppressed(e);
            } else {
                throw e;
            }
        }
    }

    System.out.println("end of method");
    return result * 2;
}

Upvotes: 1

Related Questions