Обработка ошибок в PHP-приложении
Вопрос
Как вы организуете обработку ошибок в PHP-приложении?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Ошибки движка и предупреждения превращаются в исключения (ErrorException)
Доменные исключения с понятной иерархией и полезными данными
Ловить только там, где можно обработать или добавить контекст, previous для цепочки
Глобальный обработчик фреймворка: лог, единый формат ответа, нужный HTTP-код
display_errors выключен в проде, детали только в логах и Sentry
Ожидаемые ситуации (валидация) как результат или ValidationException с кодом 422
Что могут спросить следом
- Почему нельзя показывать стек пользователю?
- Как вы ловите фатальные ошибки вроде нехватки памяти?
Разбор
Во-первых, всё превращаю в исключения: обработчик set_error_handler бросает ErrorException на предупреждения, а с PHP 7 ошибки движка и так приходят как Error. Во фреймворках это уже настроено.
Во-вторых, у предметной области свои исключения: OrderNotFound, PaymentDeclined с нужными данными в свойствах. Ловлю их там, где знаю, что делать: показать сообщение, повторить, откатить. Если оборачиваю низкоуровневую ошибку, передаю её в $previous, чтобы не терять причину.
Всё непойманное попадает в глобальный обработчик фреймворка: он пишет лог с контекстом запроса, отправляет в Sentry и отдаёт клиенту единый ответ: 404 для ненайденного, 422 для валидации, 500 для остального, без стека и деталей. В продакшене display_errors выключен. Фатальные ошибки вроде превышения memory_limit исключениями не ловятся, для них есть register_shutdown_function с error_get_last.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.