Существуют ли исключения для предотвращения сбоя системы?

16

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

Но они там, чтобы в основном защитить систему от сбоев, завершив пользовательскую программу?

Темный тамплиер
источник

Ответы:

29

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

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

Кроме того, в системах, где пользовательский ввод может быть причиной / решением проблемы, исключения могут дать пользователю подробную и полезную информацию о проблеме. Вместо слишком распространенного «Необработанное исключение произошло в ...» или «Запугивающее сообщение об ошибке прямо из SQL» вы можете сказать пользователю что-нибудь полезное или хотя бы понятное, например «Не удалось подключиться к ресурсу B.»

Бен Брока
источник
5
Я чувствую, что это самый точный ответ. Программы - это конечные автоматы, которые работают. Есть способы сломать машину, введя неверные данные, которые могут привести к ее неисправности. Исключения бросаются, чтобы предотвратить это. Иногда машина может восстановить себя, но иногда это не может.
Энди
1
Не могу ли я сделать то же самое с кодами ошибок? Вы возвращаете ошибку, а я ее обрабатываю.
Mskw
16

Исключения были созданы для упрощения обработки ошибок. Без исключений логика обработки ошибок должна распространяться по всему приложению. Любая функция, которая может привести к ошибке, должна каким-то образом возвращать статус ошибки, и каждый вызов должен сопровождаться проверкой на наличие ошибок. Часто вызывающая сторона не может сделать ничего полезного в случае ошибки и может только вернуть саму ошибку. Половина кода приложения может быть посвящена обработке ошибок. Такой код чрезвычайно хрупок. Слишком легко пропустить проверку ошибок и сбой, или, что еще хуже, вернуть неверные результаты из-за незамеченной ошибки.

За исключением, ошибки могут быть проверены только в той точке, где они могут быть обработаны. Большая часть кода приложения может быть написана прямолинейно, поскольку функции либо возвращают полезное значение, либо выдают исключение.

Кевин Клайн
источник
5

Точка исключения должна заключаться в информировании пользователя об исключительных обстоятельствах. Если с системой что-то пойдет не так, программа должна знать об этом и позволить ей * обрабатывать ее соответствующим образом.

Тем не менее, нет, исключение не существует для предотвращения "сбоя" системы. Исключение, которое дает мне понять, что есть проблема. То, как я действую, определяет, может ли система «зависать».

Также обратите внимание, что исключение не должно завершать приложение, как вы сказали. Исключение может быть обработано программистом и исправлено или превращено в какую-то значимую ошибку для пользователя.


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


источник
2
Я не согласен, это определение слишком ограничено. Только подмножество исключений должно отображаться пользователю. Исключения составляют обработка ошибок, и отказ от информации и информирование пользователя обычно является последним шагом, который не должен быть нормой. Некоторые системы предназначены для использования исключений и для некоторых видов управления потоком, таких как конец итерируемого, EOF и т. Д.
Юрген Штробель,
Юрген, я понимаю и полностью согласен с вашим комментарием. «исправлено или превращено в какую-то значимую ошибку» - разве я не передаю эту мысль этим утверждением?
Да, теперь намного лучше.
Юрген Штробель
Возможно, исключения никогда не должны показываться пользователям. (Условия, которые привели к их генерации, возможно, нужно каким-то образом сообщать пользователям, но не как исключения.) Но исключение всегда лучше, чем программа, просто выполняющая DIAF или неожиданный выход. («Каждый раз, когда я пытаюсь отсортировать свою электронную почту по имени отправителя, почтовый клиент выходит без вывода сообщений!». Независимо от того, насколько чист этот выход, он все равно ошибается.)
Donal Fellows
2

Исключения допускают современную обработку ошибок путем отделения местоположения ошибки от обработчика ошибок. Иногда это также используется для управления потоком.

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

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

Юрген Штробель
источник
Существуют ограничения на то, что операционная система может очистить. В общем, ОС не может знать, нужно ли очищать или откатывать какие-либо постоянные ресурсы (например, файлы), и не может знать, нужна ли какая-либо очистка для удаленного соединения, кроме простого закрытия соединения на локальной стороне.
8bittree
2

Это очень просто

  • Чтобы сбить только программу, а не всю систему - у нас есть [хорошие] операционные системы.
  • Чтобы сбой программы вместо игнорирования фатальной ошибки - у нас есть исключения.

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

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

Поэтому было решено - при возникновении ошибки, которую вы не учли, немедленно вылетает! AKA Исключительная обработка.

Ям Маркович
источник
1

Исключения - это просто механизм обнаружения ошибок. Сами по себе они бесполезны.

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

mouviciel
источник
0

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

Это делает код более понятным и простым в обслуживании.

Рассмотрим два фрагмента кода:

try:
    do1()  # this is obvoiusly a normal
    do2()  # program flow
except:
    oups()  # this is exception handling code

По сравнению с этим:

if foo():
    thing1()  # is this part of normal program flow?
else:
    thing2()  # or maybe this one? Or both? When?

Конечно, обработка исключений может использоваться для предотвращения сбоя программы:

try {    // very bad code
    my();
    whole();
    ugly();
    application();
    here();
} catch (Throwable t) {
    // pretend it's ok
}

но это не причина для исключений в современных языках программирования.

Вы также можете использовать whileи breakвместо, ifно это не то, что whileи breakдля.

Михал Шрайер
источник
На самом деле обработка «ненормального» потока управления происходит именно тогда, когда goto и его перерыв в друзьях являются наиболее полезными. Преимущество исключений состоит в том, что они могут пересекать границы функций и что вызывающая сторона может определить, где ее лучше всего перехватить.
hugomg
@hugomg: Другое большое преимущество исключений состоит в том, что они позволяют выполнять очистку ресурса и другие подобные действия между местом, где выбрасывается исключение, и местом, где оно обрабатывается.
суперкат