> Где используется recover в Go? (Go)

Уровень: senior · Роль: backend · Категория: Технические вопросы

Компании: InDrive, Employcity

Стек: Go

> Пример ответа

Короткий ответ

recover используется в Go для перехвата паники и восстановления нормального выполнения программы. Он работает только внутри отложенных функций (defer), и его основное назначение - предотвратить аварийное завершение горутины или всего процесса. Типичные сценарии: обработка ошибок в HTTP-серверах, graceful shutdown, изоляция сбоев в фоновых задачах, а также в библиотеках, чтобы преобразовать панику в обычную ошибку.

Подробное объяснение

recover - это встроенная функция, которая возвращает значение, переданное в panic, и останавливает процесс раскрутки стека. Ключевое ограничение: вызов recover имеет эффект только если он выполняется непосредственно внутри функции, вызванной через defer. Если вызвать recover вне defer или в отложенной функции, которая была вызвана не напрямую (например, через промежуточную функцию), он вернёт nil.

Механика работы:

  • При panic выполнение текущей функции прекращается, и начинают выполняться отложенные функции в порядке LIFO.
  • Если в одной из этих отложенных функций вызван recover, паника считается обработанной, и выполнение продолжается с точки, следующей за вызовом функции, которая содержала defer.
  • Если recover не вызван ни в одной из отложенных функций, паника распространяется вверх по стеку, и в конечном итоге программа завершается с ненулевым кодом.

Важно понимать, что recover не отменяет уже выполненные defer - все отложенные функции выполнятся, но после вызова recover выполнение продолжится в обычном режиме.

На практике

В реальном коде recover чаще всего используется на границах системы: в middleware HTTP-серверов, в обработчиках воркеров, в точках входа горутин. Это позволяет не ронять весь сервис из-за одной паники в отдельном запросе или задаче.

Распространённый паттерн - обёртка для горутины:

GO
func safeGo(fn func()) {
go func() {
defer func() {
if r := recover(); r != nil {
log.Printf("recovered from panic: %v", r)
}
}()
fn()
}()
}

Также recover используют для преобразования паники в ошибку, когда нужно сохранить тип error в публичном API библиотеки.

Пример кода

GO
func main() {
result, err := safeDivide(10, 0)
if err != nil {
fmt.Println("error:", err)
} else {
fmt.Println("result:", result)
}
}
func safeDivide(a, b int) (result int, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic recovered: %v", r)
}
}()
return a / b, nil
}

Как отвечать на собеседовании

Начни с точного определения: recover - это встроенная функция для перехвата паники, работает только внутри defer. Затем объясни механику: порядок выполнения отложенных функций, условие срабатывания, что происходит после вызова. Приведи реальный пример использования - middleware или обёртку для горутин. Упомяни ограничения: recover не работает вне defer, не перехватывает панику из других горутин, не отменяет выполнение уже запланированных defer. Заверши ответ практическим советом: не использовать recover для скрытия ошибок, а только для изоляции критических границ.

Что проверяет интервьюер

  • Понимание модели обработки паник в Go и отличие от исключений в других языках.
  • Знание ограничений recover: только в defer, только в той же горутине.
  • Умение применять recover в реальных сценариях: middleware, воркеры, graceful degradation.
  • Понимание trade-off: recover не заменяет обработку ошибок, а лишь предотвращает аварийное завершение.
  • Способность объяснить, почему recover бесполезен в обычном потоке выполнения, а не в отложенной функции.

Типичные ошибки

  • Утверждение, что recover можно вызвать где угодно - это неверно, он работает только внутри defer.
  • Попытка использовать recover для перехвата паники из другой горутины - это невозможно.
  • Игнорирование того, что recover возвращает nil, если паники не было, и путаница с panic(nil) (в Go 1.21+ это обрабатывается отдельно).
  • Чрезмерное использование recover как универсального обработчика ошибок вместо явной проверки возвращаемых значений.
  • Забывание залогировать панику - молчаливое проглатывание ошибок усложняет диагностику.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью