Как правильно обрабатывать внутренние (Internal) ошибки в бэкенд-сервисе?

Ответ

Правильная обработка внутренних ошибок (например, 500 Internal Server Error) — ключ к стабильности и отлаживаемости сервиса. Вот основные шаги:

  1. Не допускать падения сервиса. Используйте defer и recover в горутинах, обрабатывающих запросы (например, в HTTP-хендлерах), чтобы перехватывать паники. Это предотвратит падение всего приложения из-за одной неудачной операции.

    defer func() {
        if r := recover(); r != nil {
            log.Printf("Перехвачена паника: %v", r)
            // Здесь можно дополнительно логировать stack trace
        }
    }()
  2. Детальное логирование для разработчиков. Записывайте в лог всю возможную информацию: саму ошибку, трассировку стека (stack trace), ID запроса и другие контекстные данные. Эта информация бесценна для отладки.

    log.Printf("Internal error on requestID %s: %v", requestID, err)
  3. Безопасный и общий ответ клиенту. Никогда не отправляйте клиенту детали внутренней ошибки или stack trace. Это небезопасно и может раскрыть внутреннюю структуру вашего приложения. Возвращайте общий ответ.

    • Для REST API:
      http.Error(w, "Внутренняя ошибка сервера", http.StatusInternalServerError)
    • Для gRPC:
      return nil, status.Error(codes.Internal, "внутренняя ошибка сервера")
  4. Мониторинг и оповещения. Настройте систему мониторинга (например, Prometheus) и трекинга ошибок (Sentry, DataDog) для сбора и агрегации таких ошибок. Установите алерты на аномальный рост их количества, чтобы оперативно реагировать на проблемы.