Чем опасна throws Exception в сигнатуре функции | OTUS
⚡ Открываем подписку на курсы!
Проходите параллельно 3 онлайн-курса в месяц по цене одного.
Подробнее

Курсы

Программирование
Flutter Mobile Developer Подготовка к сертификации Oracle Java Programmer (OCAJP)
-8%
Алгоритмы и структуры данных
-12%
Web-разработчик на Python
-11%
Архитектура и шаблоны проектирования
-14%
JavaScript Developer. Basic Супер-интенсив «СУБД в высоконагруженных системах»
-18%
iOS-разработчик. Базовый курс
-23%
Разработчик на Spring Framework
-23%
Python Developer. Basic
-16%
C# ASP.NET Core разработчик
-18%
Разработчик программных роботов (RPA) на базе UiPath и PIX
-6%
JavaScript Developer. Professional
-9%
Android Developer. Basic
-10%
Java Developer. Professional Разработчик C# AWS для разработчиков Highload Architect Reverse-Engineering. Professional CI/CD Vue.js разработчик Agile Project Manager Нереляционные базы данных Супер - интенсив по паттернам проектирования Супер - интенсив по Kubernetes Advanced Fullstack JavaScript developer
Инфраструктура
PostgreSQL
-10%
IoT-разработчик
-12%
Administrator Linux. Professional
-11%
Базы данных
-19%
Administrator Linux.Basic
-18%
Супер-интенсив «СУБД в высоконагруженных системах»
-18%
Супер-интенсив "SQL для анализа данных"
-16%
Software Architect
-12%
Сетевой инженер AWS для разработчиков Highload Architect Разработчик голосовых ассистентов и чат-ботов Внедрение и работа в DevSecOps Администратор Linux. Виртуализация и кластеризация Нереляционные базы данных Супер-практикум по использованию и настройке GIT
Специализации Курсы в разработке Подготовительные курсы
+7 499 938-92-02

Чем опасна throws Exception в сигнатуре функции

Достаточно часто в процессе написания мы используем функции, которые выкидывают исключения (throws Exception).

String returnFoo() throws IllegalArgumentException {
    return "foo!";
}

Exception — исключение в работе программы. Оно возникает, когда что-то пошло не так. К примеру, не была проинициализирована переменная, а мы обращаемся к ней (и получаем Null Pointer Exception).

В процессе разработки ПО, разработчик может пометить, что данная функция может вызывать исключение, чтобы использующий этот метод обработал исключение. Для чего это надо? Представим, что вы подключились к базе данных, но по какой-то причине не смогли выполнить запрос. В обработке исключений вы должны сообщить (написать в лог), что произошла ошибка выполнения запроса и завершить работу с БД.

Когда мы у себя в коде вызываем функции, которые выкидывают исключения, IDE (среда разработки) заставляет нас их обработать. И сделать мы это можем двумя способами: 1. Добавить в сигнатуру, что этот метод тоже выкидывает данное исключение. Тем самым, мы как бы перекладываем обработку на другого. 2. Добавляем try{} catch {} и обрабатываем исключение сами.

И оба эти метода, в контексте автотестов, таят подводные камни при неправильном их использовании, ведь при обработке ошибок выполнение программы не прерывается.

Рассмотрим первый вариант — исключение в сигнатуре.

Предположим, у нас есть метод, который проверяет две переменные:

    public static void checkEquals() throws Exception {
    assert "a".equals("b");
}

Данная проверка заведомо будет провалена. Однако если мы в главном методе вызовем данную функцию (и тоже добавим throws в сигнатуру), то наш код выполнится без ошибок.

   public static void main(String[] args) throws Exception {
    checkEquals();
}

А что, если бы данный метод, скажем, не проверял, а обновлял данные? А мы потом ссылались на эти данные? В итоге, у нас будет ложные срабатывания в тесте, а дебаг будет крайне затруднен.

Рассмотрим теперь второй вариант, где мы обрабатываем ошибку через try{} catch{}. Обычно, начинающие автоматизаторы просто выводят стектрейс в консоль, где они видят, что данный метод завалился:

try {
    checkEquals();
} catch (Exception e) {
    e.printStackTrace();
}

Вроде бы, в данном случае все хорошо, ведь ошибка отображается в консоли. Но это более-менее работает до тех пор, пока тесты запускаются локально, а не на удаленной машине из под, к примеру, Jenkins. Ведь он может и не выводить полный лог, а ведь в этом случае вы не увидите ошибку. И, опять же, если у нас на результат выполнения данного метода завязан тест, то выполнение может пойти по совсем непредвиденному пути.

Выводы:

1) e.printStactTrace() можно использовать только для дебага. В продакшн-коде его быть не должно; 2) не используйте throws в сигнатуре методов (при разработке автотестов это нужно очень редко); 3) если вы используете конструкцию try{} catch{} , то обрабатывайте ошибку! Если у вас не получается обработать ошибку или вы не знаете, что делать, то лучше выкиньте throw new RuntimeException(e) в блоке catch , чтобы выполнение тестов сразу завершилось.

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться