На прошлой неделе я вместе с несколькими моими коллегами участвовал в большом разговоре о том, что Go обрабатывает ошибки в ожидаемых сценариях, возвращая код ошибки вместо использования исключений или какого-либо другого подобного механизма.
Это довольно спорная тема, потому что люди привыкли избегать ошибок с исключениями, но Go возвращает улучшенная версия известная модель, ранее принятая в нескольких языках, включая C, в которой ошибки передаются через возвращаемые значения.
Это значит, что ошибки маячат перед глазами программиста и заставляют его с ними бороться.
все время .
Кроме того, дискуссия сводится к тому, что в языках с исключениями каждая ошибка без каких-либо дополнительных действий несет полную информацию о том, что и где произошло, и это может быть полезно в некоторых случаях.
Однако все эти удобства имеют стоимость, которую легко сформулировать: Исключения учат разработчиков не обращать внимания на ошибки.
Печальным последствием является то, что это применимо, даже если вы блестящий разработчик, поскольку на вас влияет окружающий мир, который прощает ошибки.
Проблема появится в импортируемых вами библиотеках, в приложениях, установленных на вашем компьютере, а также на серверах, на которых хранятся ваши данные .
Рэймонд Чен описал проблему следующим образом: в 2004 году :
Написать правильный код в модели генерации исключений в некотором смысле сложнее, чем в модели генерации ошибок, поскольку все может потерпеть неудачу, и к этому нужно быть готовым.Это абсолютно верно.В модели возврата кода ошибки точка, в которой следует проверять наличие ошибок, очевидна: как только вы получаете код ошибки.
В модели исключений вам просто нужно осознавать, что ошибки могут произойти где угодно.
Другими словами, в модели возврата кода ошибки, когда кто-то пропускает обработку ошибок, это очевидно: он не проверяет код ошибки.
Однако в модели генерации исключений, если посмотреть на код, в котором кто-то обрабатывает ошибку, все не так ясно, поскольку ошибка не указана явно.
(…) Когда вы пишете код, думаете ли вы о том, какими могут быть последствия каждого исключения, которое может возникнуть в каждой строке кода? Вы должны сделать это, если собираетесь писать правильный код.
Каждая строка, которая может вызвать исключение, содержит скрытую ветвь «else» для сценария ошибки, о которой очень легко забыть.
Даже если внедрение кода обработки ошибок кажется бессмысленным повторением, его написание заставляет разработчиков помнить об альтернативном сценарии, и нередко этот код оказывается совсем не пустым.
Я не первый раз пишу об этом, и, учитывая противоречия, окружающие это утверждение, я нашел пару примеров, подтверждающих эту проблему.
Лучший пример, который я смог найти на сегодняшний день, находится в модуле пти Стандартная библиотека Python 3.3:
Каждый раз, когда кто-то вызывает этот код с неправильным именем исполняемого файла в argv, будет создаваться неиспользуемый, не подлежащий сборке мусора и неизвестный процесс для приложения Python, поскольку execlp завершится неудачно и разветвленный процесс будет проигнорирован.def spawn(argv, master_read=_read, stdin_read=_read): """Create a spawned process.""" if type(argv) == type(''): argv = (argv,) pid, master_fd = fork() if pid == CHILD: os.execlp(argv[0], *argv) (.
)
И не имеет значения, поймает ли клиент этого модуля исключение или нет. Местное обязательство не было выполнено.
Конечно, ошибку можно исправить, просто добавив try/Exception внутри самой функции spawn. Однако проблема в том, что эта логика казалась нормальной всем, кто когда-либо видел эту функцию с тех пор с 1994 года год, когда Гвидо ван Россум впервые совершил это .
Вот еще один интересный пример: $ make clean
Sorry, command-not-found has crashed! Please file a bug report at:
https://bugs.launchpad.net/command-not-found/+filebug
Please include the following information with the report:
command-not-found version: 0.3
Python version: 3.2.3 final 0
Distributor ID: Ubuntu
Description: Ubuntu 13.04
Release: 13.04
Codename: raring
Exception information:
unsupported locale setting
Traceback (most recent call last):
File "/.
/CommandNotFound/util.py", line 24, in crash_guard
callback()
File "/usr/lib/command-not-found", line 69, in main
enable_i18n()
File "/usr/lib/command-not-found", line 40, in enable_i18n
locale.setlocale(locale.LC_ALL, '')
File "/usr/lib/python3.2/locale.py", line 541, in setlocale
return _setlocale(category, locale)
locale.Error: unsupported locale setting
Это довольно серьезный сбой из-за отсутствия информации о локали в системном приложении, которое, по иронии судьбы, должно сообщать пользователям, какие пакеты устанавливать, если команда отсутствует. Обратите внимание, что вверху сетки находится ссылка на crash_guard .
Эта функция предназначена для перехвата всех исключений на краю стека и отображения подробной информации о системе и обратной трассировки, чтобы помочь решить проблему.
Этот вид парашютного перехвата довольно распространен в программировании, ориентированном на исключения, и этот подход имеет тенденцию давать разработчикам ложное ощущение хорошей обработки ошибок в приложении.
Вместо настоящего защита приложений, это становится просто удобным способом аварийного завершения работы.
В этом случае лучше выдать предупреждение, если оно вообще необходимо, и позволить программе работать в обычном режиме.
Это можно сделать, просто перенеся эту строку: try:
locale.setlocale(locale.LC_ALL, '')
except Exception as e:
print("Cannot change locale:", e)
Очевидно, это легко сделать.
Но, опять же, проблема в том, что было естественно сразу этого не сделать.
На самом деле это более чем естественно: действительно кажется лучше не считайте неверным путем.
В этом случае код сократится, он станет более простым и в результате останется только тот, который приводит к желаемому результату.
В результате, к сожалению, мы погружаемся в мир хрупкого программного обеспечения и розовых слонов.
Хотя более выразительный стиль возврата ошибок заставляет задуматься: вернет ли функция или метод в результате ошибку? Как это будет обрабатываться? Правда ли, что функция, взаимодействующая с системой, не вернет ошибку? Как решить проблему, которая может возникнуть? Результатом такой непроизвольной халатности является удивительное количество аварий и просто непредсказуемое поведение.
Оригинал Теги: #golang #перевод #исключения #Go
-
Использование Спутникового Интернета С Voip
19 Oct, 24 -
Ит-2033: Будущее Готово Устареть
19 Oct, 24 -
Предотвращение Двойной Подачи
19 Oct, 24 -
Знакомство С Временной Шкалой В Unity
19 Oct, 24 -
Игра Со Списком Условий
19 Oct, 24 -
Видеокамеры На Флэш-Картах Памяти
19 Oct, 24