More‎ > ‎

Return Statement in a Finally Block Swallows Thrown Exceptions

This short article describes the a problem which may occur in situations when a return appears in a finally block. If you execute the method in one of the samples with a parameter equals zero, an exception (divide by zero) happens. In this case, the catch block throws a UnsupportedOperationException. Unfortunately, this exception will never appear in the application, because it gets swallowed. It happens because of the return statement in the finally block. If the application expects this exception for further error handling, it will never appear and this can be a serious problem.

Return Statement in the finally Block Swallows Thrown Exceptions

In the following code the exception UnsupportedOperationException("devide by zero") will be swallowed. 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class SwallowedExceptionSample {

    private static int run(int input) {
        int result = 0;
        try { result = 3 / input;
        } catch (Exception e) {
            throw new UnsupportedOperationException("devide by zero");
        } finally {
            System.out.print("input=" + input);
            if (0 == input) {
                return result - 1;
            }
        }
        return result * 2;
    }

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

Output with wrong behavior

1
2
input=1 output=6 
input=0 output=-1

Second Version of the Sample Works As Expected

In the correct example the exception UnsupportedOperationException("devide by zero") is thrown.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class SwallowedExceptionSample {

    private static int run(int input) {
        int result = 0;
        try { result = 3 / input;
        } catch (Exception e) {
            throw new UnsupportedOperationException("devide by zero");
        } finally {
            System.out.print("input=" + input);
        }
        if (0 == input) {
            return result - 1;
        }
        return result * 2;
    }

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

Output with correct behavior

1
2
3
4
input=1 output=6 
input=0Exception in thread "main" java.lang.UnsupportedOperationException: devide by zero 
at com.sprunck.sample.SwallowedExceptionSample.run(SwallowedExceptionSample.java:10) 
at com.sprunck.sample.SwallowedExceptionSample.main(SwallowedExceptionSample.java:24)

Recommendations

  • Always use static code analysis to find this and similar problems. Good static analysis tools to start are CodePro AnalytiX and/or FindBugs.

Sponsored Link