Go: Обработка ошибок

14 вопросов

1 Что такое интерфейс error в Go?

type error interface { Error() string }. Любой тип с методом Error() string реализует error. Ошибки возвращают последним значением: func F() (int, error). Проверка: if err != nil { ... }. Стандартный способ обработки - явная проверка, без исключений.

Открыть отдельно →
2 Как оборачивать ошибки (wrapping)?

С Go 1.13: fmt.Errorf("context: %w", err) - глагол %w оборачивает err. Оригинальная ошибка сохраняется и доступна через errors.Unwrap, errors.Is, errors.As. Цепочка обёрток позволяет добавлять контекст и проверять тип/значение вверх по цепочке.

Открыть отдельно →
3 Когда использовать panic, когда возвращать error?

error - ожидаемые сбои (сеть, ввод, файл не найден). Вызывающий решает, что делать. panic - невосстановимые ошибки программиста (nil pointer, нарушение инварианта) или когда продолжать невозможно. В библиотеках предпочтительно возвращать error. В main/init иногда panic допустим.

Открыть отдельно →
4 Что такое errgroup?

Пакет golang.org/x/sync/errgroup: группа горутин с общей обработкой ошибки. При первой ошибке в одной из горутин контекст отменяется, Wait возвращает эту ошибку. Удобно для параллельных задач с единой точкой выхода по ошибке. Group создаётся с контекстом, Go запускает горутины, Wait ждёт и возвращает ошибку.

Открыть отдельно →
5 Что такое sentinel errors?

Предопределённые ошибки для сравнения: var ErrNotFound = errors.New("not found"). Проверка: if err == ErrNotFound или if errors.Is(err, ErrNotFound). Подходят для известных состояний (io.EOF, sql.ErrNoRows). Не оборачивают без %w, иначе errors.Is не найдёт.

Открыть отдельно →
6 Из чего состоит интерфейс Error?

Один метод: Error() string. Возвращает строковое представление ошибки. Тип реализует error, если у него есть этот метод. В стандартной библиотеке часто используют errors.New и fmt.Errorf, возвращающие частные типы с методом Error().

Открыть отдельно →
7 Как обработать ошибку из горутины?

Передать ошибку наружу: канал chan error, общая переменная под мьютексом, или errgroup. errgroup: запускать горутины через group.Go(), в конце group.Wait() возвращает первую ошибку. Нельзя использовать только возврат из горутины - его никто не получит.

Открыть отдельно →
8 Какие частые ошибки при работе с error?

Игнорирование: f(); g() без проверки err от f. Сравнение обёрнутой ошибки через == вместо errors.Is. Не оборачивать при добавлении контекста (теряется цепочка). Проверять err != nil до использования других возвращаемых значений. Не возвращать nil error после паники (recover).

Открыть отдельно →
9 Для чего нужны errors.Is и errors.As?

errors.Is(err, target) проверяет, есть ли в цепочке err (через Unwrap) ошибка, равная target. Для sentinel: errors.Is(err, ErrNotFound). errors.As(err, &target) находит в цепочке первую ошибку, присваиваемую в тип target (указатель на тип/интерфейс), и записывает в target. Для проверки типа обёрнутой ошибки.

Открыть отдельно →
10 Чем отличаются errors.New и fmt.Errorf?

errors.New(s) создаёт ошибку с текстом s (приватный тип в пакете errors). fmt.Errorf(format, ...) форматирует сообщение; с глаголом %w оборачивает переданную ошибку (Go 1.13+). Для оборачивания используют fmt.Errorf с %w; для простой строки - errors.New.

Открыть отдельно →
11 Как сделать свой тип ошибки?

Структура с методом Error() string. Для оборачивания и errors.Is/As реализовать Unwrap() error, возвращающий вложенную ошибку. Пример: type MyErr struct{ Err error }; func (e MyErr) Error() string { return e.Err.Error() }; func (e MyErr) Unwrap() error { return e.Err }. Проверка через errors.As.

Открыть отдельно →
12 Что делает errors.Join? (Go 1.20+)

errors.Join(err1, err2, ...) объединяет несколько ошибок в одну. Возвращаемая ошибка при вызове Error() возвращает объединённый текст. errors.Unwrap возвращает nil; для разбора используют цикл с errors.Unwrap для multi-error типов или проверяют через errors.Is по каждой.

Открыть отдельно →
13 Почему в Go нет try-catch?

Философия языка: явная обработка ошибок через возвращаемые значения. Код с ошибками виден (if err != nil), контроль потока предсказуем. Исключения скрывают ошибки и усложняют стек. В Go ошибка - часть контракта функции, вызывающий обязан её обработать или явно передать выше.

Открыть отдельно →
14 Как вернуть несколько ошибок из функции?

Обычно возвращают одну ошибку. Несколько: обёртка с цепочкой (Unwrap возвращает следующую), либо тип-коллектор (слайс ошибок), либо errors.Join (Go 1.20+). В API часто одна главная ошибка, остальные оборачиваются или логируются. errgroup собирает одну ошибку из группы горутин.

Открыть отдельно →
🧠Квиз 🏆Лидеры 🎯Собесед. 📖Вопросы 📚База зн.