Ваш recover() эту ошибку не поймает

badcasedaily1 6 часов назад Краткое содержание статьи Ваш recover() эту ошибку не поймает Средний 10 мин 4.8K Блог компании OTUS Go * Программирование * Системное программирование * Тестирование веб-сервисов * Кейс...
Will Anthropic have the best AI model at the end of October 2026?
Значимый прорыв формирует отрасль ИИ: badcasedaily1 6 часов назад Краткое содержание статьи Ваш recover() эту ошибку не поймает Средний 10 мин 4. 8K Блог компании OTUS Go * Программирование * Системное программирование * Тестирование веб-сервисов * Кейс Привет, Хабр! Почти в каждом Go‑сервисе в Kubernetes первым в цепочке стоит middleware, который ловит панику через defer и recover(), пишет её в лог и отвечает 500.
Его ставят в первый же день и больше не трогают, потому что с ним сервис переживёт любую панику в обработчике, потеряв один запрос. Где‑то рядом лежит глобальная map под кэш или счётчики, и пишут в неё из обработчиков без мьютекса, потому что «там же просто инкремент». Однажды на пике нагрузки под уходит в рестарт, потом ещё в один и в итоге в CrashLoopBackOff, а в логе остаётся одна строка fatal error: concurrent map writes и стек.
Технические детали
Строки recovered там нет ни одной, хотя recover() написан и в middleware, и в самом обработчике. Причём падает такая map не всегда. Часть гонок проходит без всякого fatal, и тогда в логе вообще ничего нет, а неверные цифры уже лежат в данных.
recover() здесь ни при чёмЧтобы это воспроизвести, хватает сервиса из одного обработчика. В нём middleware с recover(), обработчик со своим recover() и глобальная map. var hits = map // счётчики без синхронизации func recoverMW(next http.
Handler { return http. HandlerFunc(func(w http. ResponseWriter, r *http.
Отраслевые последствия
Request) { defer func() { if v := recover(); v ! ServeHTTP(w, r) }) } func hit(w http. ResponseWriter, r *http.
Request) { defer func() { if v := recover(); v ! Get("k hits++ // строка 33 fmt. Fprintf(w, "%d\n", hits) }Запись в nil‑map даёт обычную панику, и от неё middleware защищает исправно, ловит и отвечает 500.
Паника в обработчике без своего recover() тоже не роняет сервер, потому что net/http сам ловит панику, закрывает соединение и пишет стек в лог. На /hit я пустил 50 параллельных клиентов со 100 разными ключами. Здесь и дальше сервис работал на Go 1.
Этот прогресс даёт важные сигналы о будущем отрасли, и технологический мир внимательно наблюдает.





