---
title: "Exceptions and resource safety"
chapter: "09"
---

# Exceptions and resource safety

Exceptions separate normal return values from exceptional control flow.

## Checked and unchecked

Checked exceptions must be caught or declared. Runtime exceptions do not.
Use checked exceptions when a caller can reasonably recover and the API should
force a decision. Use unchecked exceptions for programming errors, violated
preconditions, and failures that most layers cannot meaningfully repair.

## Catching

Catch the narrowest useful type. Preserve the original cause when translating:
`throw new ImportException("Cannot import " + file, cause)`. Do not catch
`Exception` merely to log and continue with corrupt state.

Multi-catch handles unrelated alternatives with one block. Catch order goes
from specific to general. A `finally` block runs for normal and exceptional
completion but should not replace or suppress the original exception.

## Try-with-resources

Resources implementing `AutoCloseable` close in reverse declaration order.
If both the body and close fail, the body exception is primary and close
failures are suppressed. Inspect `getSuppressed()` during diagnosis.

```java
try (var reader = Files.newBufferedReader(path)) {
  return reader.lines().toList();
}
```

## Domain failures

Do not use exceptions for expected high-volume branching such as “not found”
when a clear result type is better. Sealed results or `Optional` can model
expected absence; exceptions remain appropriate for exceptional failure.

## Feynman check

An exception is an emergency route. Try-with-resources is a caretaker who locks
every opened door even when an emergency happens, and records secondary lock
problems without hiding the original emergency.
