Главная Новости

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"); }

Хорошая, но не увлекайтесь. Делайте минимум. Если будет больше, начнете путаться и зависать, решая, какое исключение больше подходит.

Хорошая статья

rss