Exception handling defines how a failure crosses a method boundary; cleanup can add a second failure without replacing the original one.
Java exception interview: primary failures, suppressed cleanup and catch scope
Java 8+. This is a complete program using JDK classes.
Which failure leaves try-with-resources?
If the body throws and close also throws, the body failure stays primary and the close failure is suppressed. The program prints both. Reporting only the cleanup failure would hide the operation that actually failed first.
When the body succeeds but close fails, that cleanup failure becomes the escaping failure. Resource cleanup is therefore part of the operation boundary, not a success-only detail.
Where should an exception be caught?
Catch where the caller can make a specific decision: reject an input, retry a transient operation under a budget, translate a storage failure, or abort a request. Catching every Exception inside a low-level parser and returning zero can turn corrupt data into a plausible business quantity.
Does checked mean recoverable?
No. The checked distinction affects compiler obligations, not whether recovery is feasible. A runtime exception can represent an invalid request, while a checked I/O failure can leave no safe local recovery. Document the state of the operation after failure.
A finally return can replace a pending return or exception. Avoid returning from cleanup. Preserving the original stack and suppressed failures gives the caller evidence it can use to decide whether work completed.
Working program
import java.io.IOException;
public class SuppressedImportFailure {
static final class InputHandle implements AutoCloseable {
public void close() throws IOException { throw new IOException("close failed"); }
}
public static void main(String[] args){
try(InputHandle input=new InputHandle()){
throw new IllegalStateException("parse failed");
}catch(Exception failure){
System.out.println(failure.getMessage());
System.out.println(failure.getSuppressed()[0].getMessage());
}
}
}Output
parse failed
close failedCosts and boundaries
The failure trace has constant application-sized state in this fixture. Stack capture, logging, retries and resource cleanup can have nontrivial cost in real services; do not use repeated exception creation as a normal hot-loop branch. A bounded retry also needs an idempotency decision.
Common Mistakes
- Do not return from finally.
- Do not discard the primary failure when cleanup also fails.
- Catching a failure does not imply partial mutations were rolled back.
