Я бы согласился с вашей логикой в вашем примере, однако, как вы думаете, какое исключение вы обрабатываете в своем блоке обработки исключений по сравнению с вашим программным тестом? Я подозреваю, что ваш блок обработки исключений действительно "на всякий случай, если что-то случилось". Так что все сводится к правилу обработки исключений.
Если вам не нужно обрабатывать исключение, и оно не пересекает четкую архитектурную границу, не обрабатывайте его. Если он находится на границе границы компонента, вы можете захотеть обернуть его, поместив оригинал во внутреннее исключение.
Если функциональность вызывается из кода, вы либо захотите проверить результат с помощью некоторого представления статуса, например ответа (HRESULT является ярким примером этого. 0 == SUCCESS,! = 0 == сбой), либо используйте исключения.
Тестирование на программные ошибки или сбои компонентов - это место, где вы будете использовать исключения, если вы проверяете ввод от пользователя в пользовательском интерфейсе, вы можете просто использовать логику и возвращать коды состояния, чтобы помочь сообщить об ошибке пользователю.
Наконец, подумайте и о локализации. Если вы выводите сообщение об ошибке на английском языке через систему и представляете его своему говорящему по-французски пользователю, это было бы бесполезно, и вы не хотите начинать синтаксический анализ строк в вашем пользовательском интерфейсе для генерации французской версии, поэтому исключения являются способом идти до тех пор, пока полезная нагрузка исключения содержит достаточно информации, чтобы сгенерировать полезное сообщение об ошибке, чтобы пользователь мог предпринять корректирующие действия.
Используйте код состояния, когда между компонентами имеется тесная связь, и вызывающий компонент знает, что делать в различных состояниях состояния.
Кстати, вы можете записать трассировку стека, а также просто сообщение, используя ToString (), поскольку это даст вам более полезную информацию для решения проблемы.
НТН