panic: аварийный тормоз
Ночью один упавший обработчик положил весь сервис: дежурный поднимал процесс по алерту, а клиенты получили разрывы вместо ответов. Утром в логах нашли один короткий стек-трейс. Миша разобрал, как авария дошла до самого верха.
panic прекращает нормальное выполнение и разматывает стек, выполняя defer; если панику не перехватили, программа печатает значение и стек-трейс и завершается — это аварийный тормоз для багов, а не механизм обработки ошибок.
panic — встроенная функция. Вызов panic(v) немедленно прекращает нормальное выполнение функции и запускает процесс, который называют паникой или разматыванием стека: по очереди выполняются все defer-вызовы текущей функции, потом то же самое в функции выше, и так до самого верха. Если панику никто не перехватил, программа завершается: стандартный тулчейн печатает в stderr значение v и стек-трейс паникующей горутины (трейсы всех горутин — только при GOTRACEBACK=all) и завершает процесс с кодом 2. Детали вывода — поведение реализации, а не контракт языка; гарантировано одно: необработанная паника завершает программу.
Что делает panic
func main() {
fmt.Println("начало")
panic("что-то сломалось")
fmt.Println("конец") // не выполнится
}
Вывод: сначала «начало», потом panic: что-то сломалось, потом стек-трейс. Строка «конец» не напечатается — после panic исполнение в этой функции не продолжается.
Паникует runtime
Чаще всего panic вызываешь не ты, а сам runtime. Индексация за границей слайса, запись в nil-карту, type assertion без ok, разыменование nil-указателя, деление целого на ноль — всё это паникует. Это программистская ошибка, а не ожидаемый сбой, поэтому и реакция соответствующая: упасть громко и сразу, а не продолжать с повреждённым состоянием.
Panic против error
Отсюда главное правило: panic — для багов в коде и нарушенных инвариантов, error — для ожидаемых ошибок. Сеть может не ответить, файл может не существовать — это error. Выход за границы слайса — это твой баг, тут panic уместен. Если сервис начинает паниковать на каждую ошибку клиента, он роняет весь процесс из-за одного запроса.
Вы узнаете:
- почему панику в другой горутине нельзя перехватить из main
- как читать стек-трейс при панике
Проверьте себя
var m map[string]int; m["x"] = 1. Что произойдёт?
Деление на ноль или выход за границы слайса — panic или возврат error?
Паника в фоновой горутине — что произойдёт с процессом?
правильных ответов
panic останавливает горутину и, если не вмешаться, роняет процесс. Он для инвариантов и багов; ожидаемые ошибки возвращают как error.
10 000 ₽ · 60 минут · онлайн