Когда в Go используют panic и как работает recover?
- Чем panic отличается от возврата ошибки?
panic — для невозможных ситуаций и ошибок программиста (выход за границы, nil-указатель, нарушенный инвариант), а не для ожидаемых ошибок. Panic раскручивает стек, выполняя defer. recover внутри отложенной функции останавливает панику и возвращает её значение.
- recover работает только в defer той же горутины
- Паника в горутине без recover роняет всю программу
- HTTP-серверы ставят recover в middleware, чтобы один запрос не убил сервис
А ещё Must-функции (regexp.MustCompile) паникуют при инициализации — там это уместно
Подробно
Ошибка или panic. Ожидаемые сбои (нет файла, сеть недоступна, неверный ввод) — возвращаемые ошибки. Panic — когда продолжать бессмысленно или это баг: нарушение контракта, недостижимый код, невозможность инициализации при старте.
Горутины. Паника не передаётся в родительскую горутину: необработанная паника в любой горутине завершает весь процесс. Поэтому фоновые горутины, выполняющие непроверенный код, оборачивают recover-ом.
Не перехватить: фатальные ошибки рантайма — конкурентная запись в map, нехватка памяти, взаимоблокировка всех горутин — завершают программу без возможности recover.
Пример
func safe(h http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
defer func() {
if rec := recover(); rec != nil {
log.Printf("panic: %v\n%s", rec, debug.Stack())
http.Error(w, "internal error", 500)
}
}()
h(w, r)
}
}Что хотят услышать
- Когда panic уместен.
- Механика recover через defer.
- Паника в горутине.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗panic — основной способ вернуть ожидаемую ошибку
- ✗Паника в горутине без recover завершает только эту горутину, а не процесс
- ✗recover перехватывает панику из любой горутины
- ✓panic — для ошибок программиста; recover работает только в defer
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.