TGViewer
Хэндлим тему | Дерепко Хэндлим тему | Дерепко @handle_topic · 275 subscribers
Post #29 369
Управление форматом ответов
#пост

Недавно в чате Yii Флудилочная @Kutuzov_ska столкнулся с проблемой разных ответов в dev и prod окружениях приложения на фреймворке Symfony. О проблеме можно почитать здесь.

Development

Как правило, когда мы разрабатываем приложение, мы хотим видеть как можно подробнее причину поломки нашего кода:

- Текст сообщения
- Файл, строку и код, где произошла поломка
- Stacktrace от точки входа в приложения до этой самой строчки
- Значения переменных, аргументов функций и прочее.

Обычно приложения с обработчиком исключений и ошибок это и делают: рисуют красивый UI, рисуют сниппет с ошибой и подсвечивают нужную строчку.

Даже в JSON API многие приложения конвертируют всё в JSON представление и клиенты этого API могут увидеть полный текст ошибки, stacktrace и т.п.

Production

Однако, в продакшене такое делать непозволительно опасно:

- Тексты ошибки дают злоумышленникам возможно эксплуатировать ваше приложение и найти уязвимости
- Stacktrace может раскрыть вашу внутреннюю структуру приложения
- Значения переменных могут раскрыть ваши данные для доступа к тем или иным сервисам

Чтобы такого не происходило, хорошей практикой считается сокрытие всех подробностей ошибки или исключения в конечном ответе, а залогировать ошибку можно “как есть”, считая безопасным попадания в систему сбора логов.

О надежности последнего можно говорить много, однако я бы хотел сделать упор на текст ошибки, выводимый в тело ответа.

Для клиентов API порой удобно завязаться на текст ошибки и сделать какое-то конкретное действие:

- Подождать какое-то время и отправить запрос заново
- Показать текст ошибки пользователю
- Выполнить какую-то логику, основываясь на тексте ошибки

Конечно, можно завязаться на HTTP код ответа и выполнять нужное действия, основываясь на значении этого кода, но текст ошибки иногда тоже приходится задействовать.

Чтобы ваш клиент не показал пользователю ошибку


Fatal error: Uncaught TypeError: find(): Argument #1 ($id) must be of type int, string given


Стоит как-то разделять текст, который можно показать пользователю и текст, который стоит скрыть за стандартным текстом HTTP кода: Internal server error, Bad request и другие.

Обработчик ошибок

Такое разделение, как правило, делают на стороне формирования этой ошибки – в нашем случае на бекенде.

В Yii2 есть концепция HttpException: есть несколько базовых классов, отражающие соответствующий HTTP код исключения и возможность задать свой текст ошибки, который увидит клиент. Подробнее можно почитать здесь: ссылка на документацияю.

В Symfony приложениях тоже есть аналогичный подход.

Exception Mapper

В своих проектах я предпочитаю написать свой mapper исключений в выводимый ответ:

- Создаю класс, который встраивается в логику обработки исключений
- Сформирует нужный мне формат ответа с дополнительными кодами и текстами
- Будет заниматься прочими удобствами для development окружения

Похожая схема есть и в Yii3: ссылка на документацию.

В Yii3 http stack построен на базе PSR middleware, поэтому нужно лишь добавить middleware в стек и настроить класс формирования ошибок.

В Symfony http stack построен на событийной модели, и для похожего действия нужно написать свой обработчик события onKernelException.

В Symfony приложениях я создаю несколько интерфейсов-маркеров, который могут задавать кастомный текст ошибки, который сможет увидеть клиент. Все остальные ошибки скрывают все свои детали.

Выглядит такой обработчик примерно так: ссылка на gist.

Имея собственный обработчик, этого позволяет мне внедрять множество коротких путей в разработке, уменьшая boilerplate кодовой базы. Выглядит очень просто и всегда можно изменить массово под требования.

——

Полезные ссылки:

List of http status codes
Yii Флудилочная

@handle_topic
  • 👍 5
  • 🔥 2
More from @handle_topic
  1. Sep 9, 2026Пыхник’26 — целая неделя PHP! С 28 сентября по 2 октября пройдёт Пыхник’26 — онлайн-конфер…
  2. Aug 24, 2026Мой Pull Request в vlucas/dotenv смёржили! Рад ли я? Конечно. Прихнаюсь честно, у меня это…
  3. Aug 5, 2026Jetbrains выделили LSP ядро для Java/Kotlin, так что теперь вся (а вся?) мощщщщь IDEA дост…
  4. Jul 30, 2026Вайбкодеры?
  5. Jul 19, 2026Когда выучил высоконагруженные системы @git_rebase / send memes
  6. Jun 30, 2026Jetbrains Air на Windows! Если вы вдруг разрабатываете на винде (сожалею вам), то можете п…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →