Обработка ошибок
Пример обработки ошибок можно видеть в коде программы просмотра текстовых файлов, рассмотренной в предыдущей статье, где существует вероятность возникновения проблемы при открытии заданного файла.
В конструкции try {} catch {}
не видно никаких отличий от аналогов из C++, C# и Java. Особенности обнаруживаются на более низком уровне – в реализации. В библиотеке GLib имеется средство управления исключениями времени выполнения GError. Vala преобразует его в более привычную "современную" форму, но сам по себе GError изначально был предназначен для обработки так называемых восстановимых ошибок времени выполнения, о которых ничего не известно до начала выполнения, и которые не приводят к аварийному завершению программы. Поэтому не следует напрямую использовать GError для тех исключительных ситуаций, которые можно "предсказать", например, передача отрицательного числа в функцию, которая требует параметр только со значением, большим нуля.
При возникновении необходимости в написании специфического кода для обработки исключений общая схема работы точно такая же, как при использовании любого другого языка из "C-группы". Все функции, являющиеся потенциальными источниками исключений, определяются с ключевым словом throws. Везде, где это необходимо в коде, записываются команды генерации исключений throw. Вызовы потенциально "опасных" функций помещаются в блоки try-catch.
Отличия проявляются при определении типов обрабатываемых исключений (ошибок). Исключения обладают тремя характеристиками: домен (domain), код (code) и сообщение (message). Домен определяет тип ошибки. Ближайший аналог – подкласс класса Exception в языке Java. Каждый домен исключения может содержать один или несколько кодов ошибок:
Таким образом, можно определить не только обобщённый тип возникающей проблемы, но и конкретную ошибку. Что касается сообщений, то мы уже встречались с ними – это текст, выводимый при возникновении исключительной ситуации.
Для того чтобы обрабатывать исключения в программе, вы должны определить домены с кодами ошибок и написать соответствующие обработчики для доменов. Каждому домену ошибок соответствует отдельный блок catch. Кроме того, после блока try и всех необходимых блоков catch можно добавить необязательный блок finally, который будет выполняться всегда, даже при отсутствии ошибок и их обработки, потому что иногда требуется освобождение ресурсов, захваченных внутри блока try.
Всё, сказанное выше, можно проиллюстрировать следующим примером:
Здесь метод myfunc_throw может генерировать исключения из обоих доменов, определённых в программе. Метод myfunc_catch способен генерировать исключения только второго типа, поэтому обязан обеспечить обработку ошибок из домена ErrType01. В свою очередь, метод main обеспечивает обработку всех ошибок, которые могут возникать при работе метода myfunc_catch.
Last updated
Was this helpful?