Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
IValidatableObject
с его поддержкой в куче фреймворков?фактически в статье велосипед
Я к тому что сбор ошибок через уведомления в итоге не противоречит использованию исключений для выдачи суммарного результата проверки наружу
'использовать исключения только если в программе что то пошло не так как задумано', т.е. практически отказываться от них вообще
приводит к большому количеству велосипедов.
Вполне нормально будет после валидации бросить исключение со списком ошибок, не городить же быдлокод из ненужного класса-обертки с самим объектом и коллекцией ошибок валидации, вполне нормально будет кинуть исключение, а на клиенте уже вытаскивать список ошибок из этого исключения в обработчике.
soap:fault
, и он их устраивает. Поэтому бросать надо не абстрактное исключение со списком ошибок, а FaultException
, типизованный вашим списком ошибок, и прописывать этот же список в FaultContract
— что, в итоге, и свелось к тому же самому списку ошибок, с которого начинали.ModelState
, который прекрасно валидируется во время биндинга, и на основе которого можно вернуть клиенту отлуп, который тот сможет корректно распарсить. Причем этот код можно написать один раз, запихнуть в фильтр, и забыть.Во-вторых не каждая система подразумевает наличие сторонних клиентов
В-четвертых даже любое абстрактное исключение при желании можно обернуть в FaultException
Я просто привел пример где бросок исключения для той же валидации вполне уместен и корректен
FaultException
), то выясняется, что в WCF паттерн, описанный в статье, прекрасно реализуется без какого-либо велосипеда.Но самое главное, что по факту, если не использовать нормальные исключения (т.е., использовать FaultException), то выясняется, что в WCF паттерн, описанный в статье, прекрасно реализуется без какого-либо велосипеда.
получая все их преимущества.
Код, который на уровень выше кода из пункта 2. собирает все исключения, сгенерированные кодом из пункта 2. в контейнер-коллекцию из пункта 1. Который уже выбрасывается.
Выбрасывать нужно, чтобы прокинуть сквозь уровни кода.
чтобы поймать. На нужном нам уровне.
А точно нужно прокидывать через все уровни кода? А зачем?
Теперь у вас все уровни выше знают про исключения, кидаемые ниже.
В одних случаях нужно, в других — нет. Вы архитектор, вам решать.
Я не вижу причин, почему try {… } catch {… } с указанием конкретных ожидаемых исключений может быть «неправильно».
try { user = new User; user.fill(data); user.save(); } catch (DbException e) { // чё-то не то в сохранении в БД } catch (ValidateErrors e) { // валидаторы сработали }
Вы странно рассуждаете. Как будто связность уровней своего же собственного кода — это нечто плохое.
Что плохого в явном указании интерфейса?
А если я не хочу прокидывать вообще?
Теперь у вас все уровни выше знают про исключения, кидаемые ниже. Это точно правильно?
int value = sum(2,2);
void someMethod(int arg0, const std::string& arg1, std::error_code &ec = throws());
clear_if(ec); // очистит код ошибки если не throws(). У меня размещаются в начале метода
...
throws_if<SomeExceptionClass>(ec, errcode, errcathegory); // заполнит код ошибки или выбросит SomeExceptionClass
return ...;
std::error_code
.
Замена выброса исключений уведомлениями