Card 07/ 10
All 10 cards
GotchaDifficulty: Intermediate1 min
Why catch (Exception e) {} Is the Most Expensive Line You Can Write
The import job reports success every night. The table it was supposed to fill has had the same row count for three weeks.
for (Path file : files) {
try {
importFile(file);
} catch (Exception e) {
}
}Two separate things are wrong on line 4, and either alone would be enough to lose the failure.
| What it does | Why it costs |
|---|---|
Catches Exception | Takes every runtime bug as well — a null dereference, a bad cast, an arithmetic error — none of which this handler could possibly have anticipated |
| Does nothing with it | The stack trace, the message and the cause were all captured and are now unreachable |
Catch the narrowest type you can actually respond to, and if the response is "keep going with the next file", say so and log which file and why.
for (Path file : files) {
try {
importFile(file);
} catch (ImportException e) {
failures.add(file);
log.warn("skipping {}", file, e);
}
}
if (!failures.isEmpty()) { throw new ImportFailed(failures); }An empty catch is occasionally right — a close that fails during cleanup, for instance — and when it is, a one-line comment saying why is the difference between a decision and an oversight.