Тупые вопросы про Exception

fixxxer

К.О.
Партнер клуба
uid
Тем, что у тебя получится аналог свитча на 100500 кейсов в виде catch foo - catch bar, и копипаста этого по контроллерам, вместо поддержания состояния внутри модели.
 

uid

Новичок
А как сделать без этого на моем примере? Загрузится файл на сервер или нет, мы не можем проверить на этапе валидации. Нам об этом загрузчик по факту скажет. И получается, сказать нам об этом он должен не исключением... Либо выдать исключение, но программа должна заглохнуть, а полльзователь получить 500 ошибку
Пишет файл на диск какая-то универсальная библиотека, типа Zend_File. Ей можно кидаться исключениями. Модель же должна это исключение поймать и обработать. Не вижу противоречий. А вот почему сама модель данных не может кидаться исключениями при проваленной валидации, я не понимаю и ответа на свой вопрос тут не получу.
 

fixxxer

К.О.
Партнер клуба
uid
Если притянуть за уши исключения, но при этом не выносить непонятно за каким чертом состояние валидации вне модели - то получится так:
PHP:
try {
   $model->doSmth();
} catch (ValidationException $e) {
   $errors = $model->getErrors();
   // нет никакого смысла пропихивать getErrors в $e - получится бессмысленное дублирование
}
Спрашивается, нафига тут исключение.
 

uid

Новичок
fixxxer
Т.е. это излишняя гибкость? Можно отнести к недостаткам, да. Но возможность получить всю интересующую меня информацию об ошибке в одном объекте, да еще с очень прозрачной схемой, часто перевешивает.
 

Lionishy

Новичок
uid
Всё зависит от того, что вы хотите получить. Какой у вас на уме контракт с "пользователем".

Обыкновенно получается так, что у пользователя возможности по вводу данных очень широкие, но вас эта "широта" не устраивает. Приходится перед вашим кодом, который поддерживает узкий контракт и пользователем у которого формальный контракт широк, вставлять прослойку, которая преобразует широкие данные в узкоспециальные. Такая прослойка по своей сути включает в контракт широкие данные и то, что они могут не удовлетворять специальному классу. Откуда следует, что ошибки пользователя не являются нарушением инвариантов или условий алгоритма, а следовательно и не являются исключениями. Как показывает fixxer, использование механизма исключений просто избыточно. Практически можно забивать гвозди микроскопом, но это эксцентрично...
 

uid

Новичок
Lionishy
Я понемногу начинаю понимать. Т.е. модель должна полностью взять на себя формирование данных об ошибке валидации, а не делегировать эту возможность контроллеру? Немного теряется гибкость, но зато увеличивается простота конструкции, getErrors возвращает простой массив со структурой вроде field: error_text. Так?
 

Lionishy

Новичок
uid
Я ничего не говорил относительно того, кто и где должен брать на себя ответственность аспекта проверки пользовательских данных. Я попытался объяснить почему чаще всего ошибки пользовательских данных (в мире Web особенно) вовсе не являют собой исключения.
 

fixxxer

К.О.
Партнер клуба
Lionishy
Я понемногу начинаю понимать. Т.е. модель должна полностью взять на себя формирование данных об ошибке валидации, а не делегировать эту возможность контроллеру? Немного теряется гибкость, но зато увеличивается простота конструкции, getErrors возвращает простой массив со структурой вроде field: error_text. Так?
Да не важно, что оно возвращает.
На самом деле, его и трогать-то не надо. Достаточно знать, успешно выполнена валидация или нет. Просто рендерим модель и все, в шаблон уйдет model.errors.xxx.
 

uid

Новичок
Lionishy
Я прекрасно понимаю, что ошибки ввода - не исключения в привычном понимании, просто для их обработки очень удобно использовать механизм исключений, когда объект пойманного эксепшена может многое рассказать о себе.
 

uid

Новичок
fixxxer
Возможно, я не совсем понял назначение модели и не отличаю ее от стороннего компонента.
 

Lionishy

Новичок
uid
удобно использовать механизм исключений
Может быть. Хотя мне не кажется это более удобным, чем if / else
Но что важнее, это запутывает читателя кода. Если программист видит try catch, он ожидает, что сейчас будет: ошибка исправлена или откат и перевыброс исключения наверх. А тут получается, что и программа не должна обрушиться конкретно в этом месте, и исправить ничего нельзя, и выходить из функции с исключением бессмысленно, ибо оно там не нужно.

try catch, как упоминалось в статье, которую вы рекомендовали, это просто конструкция языка, которую можно использовать для изменения потока управления. Но вот почему есть она? Вот и ответ! Создана она была для специфических целей. Но запретить её использовать вместо if / else, конечно нельзя. Это было бы глупо. Но стоит учитывать, что, возможно, не одному вам потом этот код читать... И лишний try catch может дело запутать.
 

fawkes

Новичок
Пишу обертку.
Класс А это сам класс, а класс Б его обертка для более удобной работы с классом А.
В классе А есть исключение AlphaException. В классе Б есть тоже свое исключение - BetaException.
Вопрос, как сделать вывод исключений AlphaException через BetaException?

Т.е. если чуть что, возникла ошибка AlphaException, когда я использовал методы класса А, а надо выводить через исключение, которое создано для обертки-класса Б...
Надеюсь понятно объяснил.

Прост, мне кажется, что этот вариант не правильный
Псевдокод:
PHP:
class BetaException extends Exception {}

class B
{
   final public function foo()
    {
     try {
     $obj = new A()
     $obj->baz(); //  на этом месте будет ошибка
     } cath(AlphaException $e) { 
       throw new BetaException('свое сообщение об ошибке');
    }
    }
}
 

fixxxer

К.О.
Партнер клуба
Не надо так делать.
Скорее всего, проблема в неправильном именовании исключений: к классу, который они бросают, имя исключения не должно относиться. Оно должно передавать смысл (хороший пример - spl exceptions http://php.net/manual/en/spl.exceptions.php ).
 

fawkes

Новичок
Не надо так делать.
я поэтому и спрашиваю.
Скорее всего, проблема в неправильном именовании исключений
я совершенно не про это.

_

Чтобы узнать, какая ошибка случилась в классе А, я должен поймать ее катчем и вывести.
Но если я использую этот класс в обертке. Я должен выводить ошибки из исключения связанные с оберткой (класс Б). Как это делать?
 

Вурдалак

Продвинутый новичок
Я должен выводить ошибки из исключения связанные с оберткой (класс Б)
Кому ты должен?

Но в целом, если это морда к библиотеке, то можно делать, как ты и писал выше, только не забывать передавать в конструктор нового exception'а инстанс предыдущего (третий аргумент). Специального сахара для этого нет.
 

fawkes

Новичок
Перечитал всю тему и задался вопросом, если есть условно 3 типа ошибок:
1. E_ALL ... - которые генерирует php;
2. Exception;
3. Ошибки пользователя, которые не являются исключительной ситуацией;

Нужно (и удобно ли будет) создать единый класс, для обработки всех этих ошибок?
 
Сверху