Материал проходит вычитку — возможны неточности.
Урок 55 из 118

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
  • как читать стек-трейс при панике
Задание · вопросы

Проверьте себя

Вопрос 1 из 3

var m map[string]int; m["x"] = 1. Что произойдёт?

Вопрос 2 из 3

Деление на ноль или выход за границы слайса — panic или возврат error?

Вопрос 3 из 3

Паника в фоновой горутине — что произойдёт с процессом?

Итоги

panic останавливает горутину и, если не вмешаться, роняет процесс. Он для инвариантов и багов; ожидаемые ошибки возвращают как error.

Наш сайт собирает куки. Чтобы тебе было удобнее им пользоваться. Нажимая на кнопку, ты даёшь разрешение собирать куки