alhames.ru
У меня тут возник вопрос общего характера..
Есть класс, реализующий какие-либо операции низкого уровня (например, PDO). При возникновении ошибки он кидает какой-либо свой exception.
Есть класс более высокого уровня (например, User), который использует внутри себя выше описанный класс. У этого класса тоже есть свои exceptions.
Вопрос: есть ли смысл перехватывать эксепшены низкоуровневого класса (PDOException) и кидать наружу уже экспешены более высокого уровня (UserException)?
Зачастую операции с низкоуровневым классом так или иначе приходится оборачивать в try-catch, т.к. в случае ошибки нужно выполнять какие-то дополнительные операции.

Т.е. это может выглядить примерно так:
<?php
try
{
// запрос к базе с ошибкой
}
catch (PDOException $e)
{
// операции, выполняемые в случае ошибки
throw new UserException('описание ошибки');
}


Если честно мне не очень нравится эта конструкция. Причем это я описал 2-х уровневый каскад, а зачастую у меня их получается намного больше..
Как делаете вы и почему?

@темы: Вопрос, PHP, Точка зрения

Комментарии
27.02.2014 в 17:47

Я знаю, что я гений, но мне от этого ничуть не легче.
Не знаю, как в php, но во многих языках есть у Exception свойство InnerException, при этом каскадирование выглядит так: throw new UserException('описание ошибки', $e );
При это не теряется ни какая ценная информация об ошибке, но вызвавшему Ваш код передаётся осмысленное сообщение.
Вообще, каскадирование - хорошая вещь, кроме тех случаем, когда по определённым соображениям необходимо скрывать данные об ошибках нижних слоёв.
27.02.2014 в 18:03

Если в архитектуре приложения есть выраженные уровни абстракции, то прокидывать исключения -- логично.

Например, есть UserEntity, UserPersistanceAdapter, UserCreateService, UserController. Контроллер использует сервис для выполнения задачи создания пользователя. Сервис использует какую-то реализацию адаптера, чтобы сохранить объект пользователя. Так как реализаций адаптера может быть много (PDO, mysql_, Mongo, etc.), то и вариантов исключений или (о, боже!) возвратов false из методов низкоуровневой библиотеки, тоже может быть много. Чтобы не ловить каждую разновидность исключения или возвращаемого значения, можно условиться о том, что реализация адаптера кидает исключение какого-то своего типа. И уже его ловить в контроллере. Таким образом, при изменении типа адаптера или добавлении нового, модификация внешнего ему кода не потребуется вовсе.
27.02.2014 в 19:22

alhames.ru
mikluho, Astartsky, а как быть с нагрузкой? Большое количество вложенных try-catch довольно ресурсоемко..
27.02.2014 в 20:38

тролль - это не только ценный жир, но и 3-4 легкоусвояемых коммента ежедневно
а при чём здесь нагрузка? у вас исключения вызываются 10000 раз в секунду?
запомните простое правило: исключения должны вызываться только в исключительных ситуациях
28.02.2014 в 19:05

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