Php - Хорошая ли практика создавать свои классы Exception для отлавливания разных ошибок? - Stack Overflow на русском
Опубликовано: 05.09.2018
Отвечая на вопрос
При добавлении сообщения на сайте, у меня может возникнуть разные исключения: Не корректное сообщение, Не удалось загрузить файл, ошибка PDO. Нужны ли исключения для каждой ошибки отдельно?
Нужно исходить из следующего:
что даст текст исключения для пользователя что даст разработчикуНе корректное сообщение
Не удалось загрузить файл
Это стоит отдать в браузер, чтобы пользователь понял свою ошибку и исправил ее. Старайтесь сделать такое сообщение понятным. "Не удалось загрузить файл. Используйте разрешенные форматы (docx, xlsx)"
ошибка PDO
Особенности работы сайта пользователю знать не нужно. Запишите себе в журнал, и сообщите "Ошибка сервера, попробуйте чуть позже". Может видели сообщения у Гугла и Яндекса а-ля "что-то сломалось, но мы уже знаем".
// глобальный отлов ошибок try { try { throw new Exception("DB error"); } catch (Exception $e) { // Я люблю в качестве кодов ошибок использовать 400-е и 500-е HTTP коды $errCode = $e->getCode() if($errCode >= 500) { syslog(LOG_ERR, '[Sign][docs.list][error]MySQL is gone away'); http_response_code($errCode); throw new Exception("Ошибка сервера, попробуйте чуть позже"); } } } catch (Exception $e) { // выводим ошибку пользователю }Кстати, писать можно в syslog , его PHP-программисты почему-то незаслуженно забыли. А если к сислогу прикрутить что-то типа ELK, то можно отслеживать динамику ошибок и настроить уведомления.
Если в каком-то глубоко вложенном методе что-то пошло не так, то бросить исключение - как экстренное всплытие. Это лучше, чем назад по цепочке возвращать null/false. Ваш код станет чище.
Пример:
try { // пробуем получить координаты по картам Гугла $this->geoPositionGoogle($data); } catch (Exception $e) { // если не получилось, пробуем по картам Яндекса $this->geoPositionYandex($data); }Его суть - в проверке пришедшего и ожидаемого значений. Я использую чаще всего в двух случаях:
много потенциальных точек возникновения ошибок. У меня это электронная подпись документов (может отказать сеть, база, скрипт подписания, и так далее). Подробный отчет об ошибках значительно облегчает диагностику проблем взаимодействие с внешними сервисами, где что-то может измениться без ведома программистаПример обмена с 1С:
switch($row['SECTION_TYPE']) { case 'directionBonus': // Ожидается, что название будет начинаться со слова "Бонус" if(!preg_match('~^Бонус\s+(.*)$~i', $row['SECTION_NAME'], $m)) throw new Exception("Wrong name"); break; case 'groupDDP'; // Ожидается, что название будет начинаться с кода раздела if(!preg_match('~^([0-9]+\.[0-9]+\.[0-9]+)\s+(.*)$~i', $row['SECTION_NAME'], $m)) throw new Exception("Wrong name"); break; default: // Ожидается, что других вариантов нет throw new Exception("No such case"); }Хорошая, но не увлекайтесь. Делайте минимум. Если будет больше, начнете путаться и зависать, решая, какое исключение больше подходит.
Хорошая статья