Набор параметризованных исключений
От: Sorc17 Россия  
Дата: 22.07.11 11:29
Оценка:
Всем привет.

Хочу сделать сабж. Сейчас объясню. Допустим у меня есть две исключительных ситуации в программе: "Номер заказа %d неверный." и "Количество упаковок должно быть от %d до %d." Эти исключения пусть принадлежат одному классу исключений LimitException. В месте где происходят исключения, туда нужно подставить конкретные значения вместо %d. Понятное дело, писать везде:


throw new LimitException(sprintf("Номер заказа %d неверный.", num));


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


throw new LimitException(exceptions['ORDER_NUM'](num));
throw new LimitException(exceptions['PACKS_COUNT'](min, max));


Народ говорит что так делать можно и некоторые так или подобным образом и поступают, и что ещё есть вариант сделать два наследника LimitException: OrderNumberException и PacksCountException и юзать их:


throw new OrderNumberException(num);
throw new PacksCountException(min, max);


но мне кажется последний вариант как-то не очень, хотя бы потому, что у меня сейчас 95 подобных исключтельных ситуаций и делать 95 наследников, а потом писать пару десятков catch в конце скрипта ... К тому же может быть оно ещё и точки зрения ООП не расово, по сути получается класс строк, в которых к примеру второе слово в строке параметризовано. Хотя может с точки зрения ООП это вполне ок. Не знаю.

Посоветуйте какие ещё есть годные варианты и как народ делает в своём серьёзном бизнесе(тм) такие вещи.
Для нас [Thompson, Rob Pike, Robert Griesemer] это было просто исследование. Мы собрались вместе и решили, что ненавидим C++ [смех].
Re: Набор параметризованных исключений
От: vmpire Россия  
Дата: 22.07.11 12:41
Оценка: +1
Здравствуйте, Sorc17, Вы писали:

S>Посоветуйте какие ещё есть годные варианты и как народ делает в своём серьёзном бизнесе(тм) такие вещи.

В серьёзном бизнесе(тм) делают так: если это ошибка внутренняя, которая не из за ошибочных действий пользователя (что есть норма), то кидают исключение одного-трёх-пяти типов, отличающихся только сообщением. Количество исключений зависит от количества вариантов их обработки.
Формировать текст можно простой самописной обёрткой над ресурсами со встроенными возможностями форматирования, по синтаксису будет похоже на ваш вариант.
А вот если это ошибка из-за действий пользователя или какая-то другая в норме ожидаемая ситуация, то это вообще не Exception, а обычная валидация, тут проблем с формированием исключений быть не должно за их отсутствием
Re[2]: Набор параметризованных исключений
От: Sorc17 Россия  
Дата: 23.07.11 10:25
Оценка:
Здравствуйте, vmpire, Вы писали:

V>А вот если это ошибка из-за действий пользователя или какая-то другая в норме ожидаемая ситуация, то это вообще не Exception, а обычная валидация, тут проблем с формированием исключений быть не должно за их отсутствием


Спасибо, мне вот именно этих слов так не хватало
Для нас [Thompson, Rob Pike, Robert Griesemer] это было просто исследование. Мы собрались вместе и решили, что ненавидим C++ [смех].
Re[2]: Набор параметризованных исключений
От: Sorc17 Россия  
Дата: 23.07.11 11:53
Оценка:
Здравствуйте, vmpire, Вы писали:

V>В серьёзном бизнесе(тм) делают так: если это ошибка внутренняя, которая не из за ошибочных действий пользователя (что есть норма), то кидают исключение одного-трёх-пяти типов, отличающихся только сообщением. Количество исключений зависит от количества вариантов их обработки.

V>А вот если это ошибка из-за действий пользователя или какая-то другая в норме ожидаемая ситуация, то это вообще не Exception, а обычная валидация, тут проблем с формированием исключений быть не должно за их отсутствием

А если ошибка может произойти и потому что пользователь ввёл не правильные данные и в результате вычислений? Ну например, пользователем был введён номер заказа которой не существует и в то же время какая-нибудь функция поиска вычислила номер заказа которого не существует. Ошибка одна и та же. Получается надо делать одинаковую ошибку и исключение. Хаоса не возникнет?
Для нас [Thompson, Rob Pike, Robert Griesemer] это было просто исследование. Мы собрались вместе и решили, что ненавидим C++ [смех].
Re[3]: Набор параметризованных исключений
От: Sinix  
Дата: 23.07.11 12:39
Оценка:
Здравствуйте, Sorc17, Вы писали:

S>А если ошибка может произойти и потому что пользователь ввёл не правильные данные и в результате вычислений? Ну например, пользователем был введён номер заказа которой не существует и в то же время какая-нибудь функция поиска вычислила номер заказа которого не существует. Ошибка одна и та же. Получается надо делать одинаковую ошибку и исключение. Хаоса не возникнет?


Первое обычно отсекается валидацией в UI-фреймворке, второе — простым ArgumentException/InvalidOperationExcepton. Мне за всё время работы практически не приходилось создавать свои типы исключений — имхо, вообще не стоит строить на них логику.
Re: Набор параметризованных исключений
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.07.11 11:30
Оценка:
Здравствуйте, Sorc17, Вы писали:

S>но мне кажется последний вариант как-то не очень, хотя бы потому, что у меня сейчас 95 подобных исключтельных ситуаций и делать 95 наследников, а потом писать пару десятков catch в конце скрипта ...

1. Не очень понятно, зачем писать пару десятков catch в конце скрипта. Разве в С++ недостаточно написать catch(le &LimitException)?
2. Фактически, все наследники перегружают только конструктор, другого поведения у них нет. Поэтому вместо введения лишних классов достаточно наклепать функций-конструкторов, которые стряпают нужный объект. Зачем запихивать эти функции в какой-то хешмэп, мне совершенно непонятно. Хочется отложить обнаружение опечаток в имени конструирующей функции до рантайма?
3. Если класс LimitException — ваш, то лучше спрятать функции по генерации исключений внутрь него. И писать
throw LimitException::new_order_num(num);

Зачем вам показывать эти строки наружу? Они никогда не планируются к использованию за пределами конструктора исключения.
4. В принципе, вместо возврата исключения из функции можно его же там и бросить.
LimitException::throw_new_order_num(num)
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.