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