Ответ вслух Middle Ошибки, defer, panic и recover обновлено

Обработка ошибок в Go-сервисе

Вопрос

Как вы обрабатываете ошибки в Go-сервисе от репозитория до HTTP-ответа?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

В репозитории ошибку драйвера превращаю в доменную там, где это имеет смысл: sql.ErrNoRows становится ErrNotFound, нарушение уникальности становится ErrConflict. Остальное оборачиваю с контекстом: fmt.Errorf("get order %d: %w", id, err).

Что должно прозвучать в ответе

  • Ошибки как значения, проверка сразу после вызова

  • Обёртка с контекстом через `%w` на каждом уровне, без дублей логирования

  • Sentinel и свои типы для доменных ошибок, проверка errors.Is/As

  • Маппинг на HTTP-статус в одном месте (handler или middleware)

  • Логировать один раз на верхнем уровне, клиенту не отдавать внутренние детали

  • recover в middleware на случай паники

Что могут спросить следом

  • Как понять, где именно возникла ошибка без стека?
  • Когда ошибку можно проигнорировать?

Разбор

В репозитории ошибку драйвера превращаю в доменную там, где это имеет смысл: sql.ErrNoRows становится ErrNotFound, нарушение уникальности становится ErrConflict. Остальное оборачиваю с контекстом: fmt.Errorf("get order %d: %w", id, err). На уровне сервиса тоже добавляю контекст, но не логирую: если логировать на каждом уровне, одна ошибка даст пять строк в логах. Вверху, в HTTP-обработчике или общем middleware, одна функция маппит ошибки на статусы через errors.Is и errors.As: NotFound в 404, ValidationError в 400 с полями, остальное в 500 с общим текстом, а подробности с request id в лог. Цепочка контекстов в сообщении заменяет стек: по ней видно путь. Плюс recover-middleware, чтобы паника в одном запросе не роняла сервер. Игнорирую ошибку только осознанно и с комментарием, например Close у файла, открытого на чтение.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме