Microsoft и SOLID правы.
Правильный путь - это исключения в соответствии со стандартными методами (и c #), независимо от других соображений, например, производительности.
Вообще говоря, существует два типа ошибок: техническая и бизнес-логика.
Невозможность подключения к БД, получение 500 от службы REST и т. Д. ... носят технический характер, и, поскольку они могут быть временными, вы можете попытаться выйти из этой ситуации, иногда безуспешно, что в конечном итоге вызывает Business Orchestration / Сбой процесса.
Ошибки бизнес-логики, такие как «Клиент уже существует», «Недействительные банковские реквизиты», «Входные данные не в правильном формате» не являются временными и определяются исключительно бизнес-правилами (некоторые неявные, другие явные) и будут Остановите и остановите ваш процесс без возможности восстановления, просто потому, что что-то не в надлежащем / ожидаемом состоянии.
Существует причина, по которой мы используем исключения (как технические артефакты), и заключается в том, чтобы правильно обрабатывать эти жесткие остановки.
Каждый раз, когда вы генерируете исключение, приложение перемещается обратно по стеку до первого доступного обработчика исключений, способного обработать такое исключение, возвращая элемент управления вам и в известное место, где что-то произойдет (телеметрия, ретросброс, показ диалога пользователю ...)
Любой механизм, пытающийся заменить это распространение (Ошибка), должен полагаться, например, на перехват возвращаемого значения методов для обеспечения возврата статуса или принудительного включения параметра out во все сигнатуры ваших методов, что будет иметь ужасный побочный эффект. эффекты в вашей реализации.
Да, иногда ваш текущий дизайн выглядит «слишком плоским», что вы склонны угонять возвращаемое значение тут и там, создавая сильно связанный компонент, но вы никогда не сможете сказать, как будет расти сложность системы, что означает, что в какой-то момент вы будете расширять вашу систему дополнительными слоями, и, скорее всего, подход «замещающий механизм» не подойдет, и вы будете вынуждены поддерживать их, как обычный, так и творческий.
Таким образом, попытка реализовать собственное решение создаст тесно связанные технические требования, которые должны поддерживаться повсеместно, что с точки зрения архитектуры просто «нехорошо» (не очень хорошая практика)
ЕСЛИ любая служба, которую вы потребляете, не в состоянии выдать значимую «ошибку», она хорошо структурирована, значит, служба не разработана должным образом, и проблема переходит на сторону клиента (говоря в терминах SOA).
Единственное «наиболее правильное» решение, не оставляющее хаоса в вашем Клиенте, - это создание прокси для Службы, УВАЖАЯ правила, требуемые вашим подходом к реализации.
Моя рекомендация по обработке ошибок очень проста, придерживайтесь правил, которые хорошо известны и действуют в течение десятилетий, и не пытайтесь обойти это самостоятельно, или вы столкнетесь с слишком большим количеством проблем, создайте прокси для каждый сервис и должным образом интегрировать их в вашу кодовую базу (модульное тестирование и т. д.)
Что касается предупреждений, никто не рекомендует обрабатывать это с помощью исключений. Эти «предупреждения» в вашем вопросе являются нормальным выводом при взаимодействии со службой / логическим состоянием, поддерживаемым бизнес-логикой, таким образом, место для обработки этого состояния находится в Договоре данных, возвращающемся из Службы, опять же, если Служба настолько ужасно разработана, что отвечает вам просто текстовой строкой, содержащей слово «предупреждение», и вы вынуждены анализировать эту строку в обратите внимание на ситуацию, и ваш прокси-сервер должен проверить ее и предоставить клиенту значимый и хорошо структурированный вывод.