Exceptions¶
Exceptions transfer control when a method cannot fulfill its normal contract. They should describe failures, not replace ordinary branching.
Checked and unchecked¶
- checked exceptions must be caught or declared and can describe recoverable conditions a caller is expected to consider;
RuntimeExceptionsubclasses commonly signal programming errors, invalid arguments, illegal state, or failures impractical to recover from locally;Errorgenerally represents serious runtime conditions application code should not routinely catch.
This taxonomy does not decide an API automatically. Consider whether callers can meaningfully recover, whether the failure is part of the abstraction, and how the API composes.
Preserve context¶
static String readUtf8(Path path) {
try {
return Files.readString(path, StandardCharsets.UTF_8);
} catch (IOException cause) {
throw new UncheckedIOException("failed to read " + path, cause);
}
}
Wrapping preserves the cause. Messages should add actionable context without including secrets or sensitive contents.
Resource safety¶
Use try-with-resources for AutoCloseable values. It closes resources in
reverse declaration order and preserves close failures as suppressed exceptions
when another exception is already propagating.
Practices¶
- catch the narrowest exception you can handle;
- do not log and rethrow at every layer;
- restore the interrupt status or propagate
InterruptedExceptionwhen a layer cannot complete the cancellation policy; - avoid returning
nullmerely to hide failure; - translate low-level exceptions at abstraction boundaries while retaining cause.