Card 04/ 10
Catch vs Declare vs Wrap a Checked Exception
Three legal responses, and choosing by whichever silences the compiler catches everything three frames too early.
A method that receives a checked exception can catch it and handle it, declare it with throws so its caller decides, or wrap it in an exception of its own type, keeping the original as the cause. The right choice depends on which method can do something about the failure.
| Response | Written | Says to your caller |
|---|---|---|
| Catch | try { … } catch (IOException e) { … } | I dealt with it; carry on |
| Declare | void load() throws IOException | This can fail your way; you decide |
| Wrap | throw new ConfigException("…", e) | It failed, in my terms rather than the library's |
The decision rule. Catch only where you can do something: retry, fall back to a default, tell the user. Declare when the caller is the one with the context. Wrap when the exception's type would leak an implementation detail your caller should not know about.
Rates load() {
try {
return parse(Files.readString(path));
} catch (IOException e) {
throw new ConfigException("cannot read rates from " + path, e);
}
}The second argument on line 5 is the part that matters. Passing the original exception as the cause keeps its stack trace attached, so the log shows both what your code was trying to do and which line underneath failed.
← → move through sections and cards