Suppressed Exceptions in Try-With-Resources
Fast recall
Quick revision
Core answer
addSuppressed; callers inspect them with getSuppressed(). If the body succeeds, the first close failure is primary and later close failures are suppressed. A naive manual finally can replace an earlier failure, but careful manual code can preserve it too.Whether you understand which exception is primary when both the body and close() throw, and how to retrieve the other
Thinking the close() exception wins (as in manual finally) and that the original is lost
Contrast with manual try-finally where the close exception masked the real one, and mention addSuppressed/getSuppressed
Interview-ready guide
Interview answer
Suppressed exceptions preserve secondary cleanup failures. When the try body throws, its exception stays primary and failures from closing resources are attached to it. If the body succeeds, the first close failure becomes primary and later close failures are suppressed under it.
I inspect them with getSuppressed or the Suppressed lines in a trace. This avoids the common naive-finally bug where a close exception replaces the body exception, although manual code could preserve both if written carefully.
Suppressed Exceptions in Try-With-Resources
Direct Answer
When the try body throws and closing also throws, the body exception remains primary and each close failure is attached through addSuppressed; callers inspect them with getSuppressed(). If the body succeeds, the first close failure is primary and later close failures are suppressed. A naive manual finally can replace an earlier failure, but careful manual code can preserve it too.
Code Example
The body error is caught as primary; the close() error shows up under getSuppressed().
static class Faulty implements AutoCloseable {
public void work() { throw new RuntimeException("primary: work failed"); }
public void close() { throw new RuntimeException("suppressed: close failed"); }
}
public static void main(String[] args) {
try (Faulty f = new Faulty()) {
f.work(); // throws primary
} catch (RuntimeException e) {
System.out.println(e.getMessage()); // primary: work failed
for (Throwable s : e.getSuppressed()) {
System.out.println(" " + s.getMessage()); // suppressed: close failed
}
}
}
The body's exception is primary; the close() failure is preserved as suppressed, not lost.
Common Mistakes & Pitfalls
- Assuming the
close()exception wins. In try-with-resources, the body exception is primary. - Forgetting
getSuppressed()exists. The close failure is still recorded — go read it. - Replicating the old
finallybug by manually closing and rethrowing in a way that drops the original. - Ignoring 'Suppressed:' lines in a stack trace — they often explain a secondary cleanup failure.
Check your understanding
Answer these without looking back at the article.
- How do you access suppressed exceptions in Java?
- Can you manually add suppressed exceptions to an exception?
- How does try-with-resources handle suppressed exceptions with multiple resources?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.