Unit 13 · lesson
Preserve Context Instead of Swallowing Failure
This anti-pattern makes debugging harder:
try {
riskyOperation();
} catch (Exception ex) {
// ignore
}
The program may continue, but the evidence is gone.
A silent catch can turn an obvious failure into corrupted or incomplete state that appears much later.
Context is not the same as dumping everything
Useful failure context may include:
operation attempted
record/key/input being processed
expected constraint
exception type/cause
whether the operation partially changed state
Do not include passwords, secrets, private student information, or unnecessary sensitive data in logs or exception messages.
Observability must respect data boundaries.
Preserve causes when translating
catch (NumberFormatException ex) {
throw new IllegalArgumentException("invalid match number: " + text, ex);
}
Passing ex as the cause preserves the lower-level failure chain.
A caller can see both:
domain message: invalid match number
caused by: numeric parsing failure
Clean up is different from hiding failure
Some operations require cleanup whether they succeed or fail. Java's resource-management features handle this more safely than giant finally blocks in many cases; Unit 14 will use try-with-resources.
The principle now is:
cleanup should restore/release resources, not rewrite history and pretend the operation succeeded.
Preserve Version 1
Take a small program that fails on one input.
Do not edit the only copy until the failure evidence is recorded.
Create:
Version 1 source
failing input
exception type
relevant message
first relevant program line
root assumption
Then create Version 2 with a controlled handling policy.
Run:
- the original failure case;
- one normal case;
- one boundary case.
Failure message review
Compare:
ERROR
with:
match number must be an integer; received: X12
The second is more actionable, but context can also become too verbose or expose data. Write messages for the person or layer that needs to respond.
Evidence
Submit a before/after failure report. Your Version 2 must answer:
- Was the failure recovered, translated, or propagated?
- What information was preserved?
- What sensitive/unnecessary information was intentionally excluded?
- Which regression cases prove normal behavior still works?
A program that catches every exception and prints ERROR has less observability, not more robustness.