Нужно ли описывать все исключения в блоке кода и как это делать в Java
Что проверяют
Различаете ли вы проверяемые и непроверяемые исключения и понимаете ли главное правило: ловить там, где есть что сделать с ошибкой. Заодно смотрят, знаете ли вы try-with-resources и что происходит с причиной при заворачивании.
Как отвечать
Описывать все подряд не нужно. Компилятор требует реакции только на checked, то есть наследников Exception, кроме RuntimeException: их либо перечисляют в throws, либо ловят. Unchecked ловить обычно не надо, это ошибки в коде, и они должны дойти до общего обработчика, который запишет их в лог и вернёт клиенту ответ.
Практическое правило: catch пишется там, где можно принять решение (повторить, подставить значение по умолчанию, вернуть ошибку валидации). Если решения нет, исключение пробрасывают.
public Config load(Path path) throws IOException {
try (var reader = Files.newBufferedReader(path)) {
return parse(reader);
} catch (ParseException e) {
throw new ConfigException("Некорректный конфиг: " + path, e);
}
}Полезно упомянуть: несколько типов в одном блоке пишутся через |, ресурсы закрываются try-with-resources, а при заворачивании причина всегда передаётся вторым аргументом.
Где спотыкаются
Ставят catch (Exception e) вокруг всего метода и глушат его пустым блоком или printStackTrace. Ошибка исчезает, а система продолжает работать на неверных данных. Отдельный случай InterruptedException: его нельзя просто проглотить, флаг восстанавливают через Thread.currentThread().interrupt().
Пишут throws Exception в сигнатурах всего слоя. Вызывающий код перестаёт понимать, что реально может произойти, и вынужден ловить всё сразу, а компилятор больше ничем не помогает.
Открывают поток и не закрывают его, полагаясь на сборщик мусора, либо заворачивают исключение без причины: throw new ServiceException(e.getMessage()). В логе остаётся одна строка без стектрейса исходной ошибки, и искать источник негде.