Исключения и коды ошибок: правильное их смешивание

5 ответов

Есть ли хорошие примеры концепции смешивания исключений и кодов ошибок?

Да, boost.asio - это повсеместная библиотека, используемая для сетевой и последовательной связи. в C ++, и почти каждая функция имеет две версии: выдача исключений и возврат ошибок.

Например, iterator resolve(const query&) выбрасывает boost::system::system_error при неудаче, а iterator resolve(const query&, boost::system::error_code & ec) изменяет ссылочный аргумент ec.

Конечно, то, что является хорошим дизайном для библиотеки, не является хорошим дизайном для приложения: приложение приложит все усилия, чтобы последовательно использовать один подход. Тем не менее, вы создаете библиотеку, поэтому, если вы готовы к этому, использование boost.asio в качестве модели может быть осуществимой идеей.

13
ответ дан 28 November 2019 в 18:09
поделиться

Исключения хороши, когда код, который должен обрабатывать ошибку, находится далеко (многоуровнево) от сайта, обнаружившего проблему.

Коды состояния хороши, если ожидается, что отрицательный статус будет возвращаться «часто», и если код, вызывающий вас, должен решать эту «проблему».

Естественно, здесь есть большая серая зона. Что часто, а что далеко?

Я бы не советовал вам предлагать обе альтернативы, так как это в основном сбивает с толку.

7
ответ дан 28 November 2019 в 18:09
поделиться

Заменяют ли исключения коды ошибок полностью или, может быть, мне нужно использовать их только для «смертельных случаев»?

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

  • EINTR: операция прервана, иногда стоит перезапустить операцию, а иногда это означает, что «пользователь хочет выйти из программы»
  • EWOULDBLOCK: операция неблокирующая, но данные не могут быть переданы сейчас. Если вызывающий ожидает надежного неблокирующего поведения (например, доменные сокеты UNIX), это фатальная ошибка. Если вызывающий абонент проверяет оппортунистически, это пассивный успех.
  • частичный успех: в контексте потоковой передачи (например, TCP, дисковый ввод / вывод) ожидаются частичные чтения / записи. В отдельном контексте обмена сообщениями (например, UDP) частичное чтение / запись может указывать на фатальное усечение.

Когда вы работаете на этом уровне, ясно, что исключения не подходят, потому что автор реализации не может предсказать, какие «ответы об ошибках» на самом деле будут рассматриваться как критические сбои данным пользователь или просто нормальное поведение.

2
ответ дан 28 November 2019 в 18:09
поделиться

Заменяют ли исключения коды ошибок полностью или, может быть, мне нужно использовать их только для «смертельных случаев»?

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

Является ли смешивание двух парадигм (исключений и кодов ошибок) хорошей идеей?

Я думаю, что вы должны основывать свою реализацию на кодах ошибок и использовать исключения в действительно исключительных ситуациях (например, нет памяти, или что вы должны поймать один брошенный вам). в противном случае предпочтите коды ошибок.

Это хорошая идея, чтобы предоставить пользователю две концепции?

нет. не все используют исключения, и им не гарантируется безопасное пересечение границ. разоблачать их или бросать в домен клиента - плохая идея, и клиентам сложно управлять предоставляемыми вами API-интерфейсами. им придется обрабатывать несколько выходов (коды результатов и исключения) и некоторым придется обернуть ваши интерфейсы, чтобы использовать библиотеку в их кодовой базе. Коды ошибок (или что-то подобное) являются наименьшим общим знаменателем здесь.

Как бы вы это реализовали?

Я бы не стал подвергать клиентов исключениям, это больше для поддержания и может быть изолированным. Я бы использовал коды ошибок или простой тип, который предоставляет дополнительные поля, где это необходимо (например, строковое поле, если вы предложите конечному пользователю предложение по восстановлению). и я бы постарался сохранить его на минимальном уровне. также предоставьте им средства для тестирования с расширенной диагностикой для развития.

3
ответ дан 28 November 2019 в 18:09
поделиться

Здесь необходимо учитывать один важный момент: это механизм блокировки, выдающий коды ошибок в отношении деталей того, что выходит из строя, это все равно, что сообщать сборщику замка, что первые 3 из 4 контактов внутри замка он имеет правильно .

Вы должны опустить здесь как можно больше информации и убедиться, что вашей процедуре проверки ВСЕГДА требуется одинаковое количество времени для проверки карты, чтобы атака по времени была невозможна.

Но вернемся к исходному вопросу: в общем, я предпочитаю, чтобы во всех случаях возникало исключение, чтобы вызывающее приложение могло решить, как оно хочет обработать их, поместив вызов в блок try / исключением.

4
ответ дан 28 November 2019 в 18:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: