Reputation: 71
I'm aware that try-with-resources statement was introduced to cure (or) prevent exception masking.
Consider the following code:
class TestExceptionSuppressing {
public static void main(String[] args) {
try {
testMethod();
} catch (Exception e) {
System.out.println(e.getMessage());
for (Throwable t : e.getSuppressed()) {
System.err.println("Suppressed Exceptions List: " + t);
}
}
}
static void testMethod() {
try (InnerClass inner = new InnerClass()) {
throw new IOException("Exception thrown within try block");
} catch (Exception e) {
throw new RuntimeException(
"Exception thrown within catch block.Hence exception thrown within try block will be lost (or) masked");
}
}
static class InnerClass implements AutoCloseable {
@Override
public void close() throws Exception {
throw new Exception("Exception thrown in close method will be tacked on to existing exceptions");
}
}
}
Output: Exception thrown within catch block.Hence exception thrown within try block will be lost (or) masked
Apparently, exception thrown in catch block of testMethod() has masked both the io exception thrown in try block and also the exception suppressed and added to this io exception(thrown in close method )
This code example might prove that try-with-resources may not completely prevent exception masking.
I'm aware things are mixed up in here and might be confused but is a possible case to happen. My question is, is there a way to prevent this scenario i.e. exception masking to still happen even when using try-with-resources statement?
Upvotes: 3
Views: 1938
Reputation: 58782
You can keep the original exception if you use RuntimeException(String, Throwable)
Constructs a new runtime exception with the specified detail message and cause.
throw new RuntimeException(
"Exception thrown within catch block won't be lost (or) masked", e);
If you want to add the suppressed try and resources exception, you need to use the addSuppressed(Throwable) method, in your case:
RuntimeException runtimeException = new RuntimeException(
"Exception thrown within try block won't be lost (or) masked", e);
runtimeException.addSuppressed(e.getSuppressed()[0]);
More info in Suppressed Exceptions and Try With Resources
However, just because the CloseException is supressed in this scenario, it doesn't mean this suppressed exception has be ignored. To address this concept of suppressed exceptions, two new methods and a constructor have been added to the java.lang.Throwable class in Java 7.
public final void addSuppressed(Throwable exception)
Upvotes: 4