11 вопросов
Go использует явную обработку ошибок через возвращаемые значения вместо исключений. errors.Is, errors.As, оборачивание через %w - ключевые инструменты работы с ошибками.
Go использует явную обработку ошибок через возвращаемые значения, а не исключения. Идиоматический паттерн: result, err := f(); if err != nil { return err }. Нет try/catch - это сознательное решение дизайнеров Go.
Подробнее →errors.New("сообщение") создаёт новое значение, реализующее интерфейс error. Для форматированных ошибок: fmt.Errorf("ошибка: %v", details). В Go нет конструкций new Error() (JavaScript) или throw (Java).
Подробнее →Интерфейс error содержит один метод: Error() string. Любой тип с этим методом является ошибкой. Можно создать свой тип ошибки с дополнительными полями.
Подробнее →var ErrNotFound = errors.New("not found") на уровне пакета? 🟢 Лёгкий
▶
Sentinel errors (ошибки-значения) объявляют как переменные пакета, чтобы сравнивать через errors.Is(err, ErrNotFound), а не по тексту. Сравнение по тексту хрупкое - любое изменение сообщения ломает код. errors.Is работает с цепочкой обёрнутых ошибок.
Подробнее →errors.Is(err, target)? 🟡 Средний
▶
errors.Is рекурсивно проходит по цепочке обёрнутых ошибок (через Unwrap()) и сравнивает каждую с target. Это надёжнее, чем err == target, потому что работает с обёрнутыми ошибками.
Подробнее →Глагол %w в fmt.Errorf оборачивает ошибку, сохраняя цепочку. Обёрнутую ошибку можно проверить через errors.Is и errors.As. Глагол %v только добавляет текст, но теряет связь с оригинальной ошибкой.
Подробнее →errors.As(err, &target)? 🟡 Средний
▶
errors.As ищет в цепочке ошибку определённого типа и записывает её в target. Полезно для получения дополнительных данных из кастомных ошибок.
Подробнее →errors.Join(err1, err2) (Go 1.20+)? 🟡 Средний
▶
errors.Join объединяет несколько ошибок в одну. Результат содержит все переданные ошибки, и errors.Is/errors.As проверяют каждую из них. Полезно при параллельной обработке, когда нужно собрать ошибки из нескольких горутин.
Подробнее →errors.Is проверяет всю цепочку обёрнутых ошибок (unwrap). err == ErrNotFound не работает с обёрнутыми fmt.Errorf("%w", err). Строковое сравнение хрупко - текст может измениться. errors.As - для проверки типа ошибки и извлечения данных из неё.
Подробнее →err := fmt.Errorf("wrap: %w", os.ErrNotExist); errors.Is(err, os.ErrNotExist)? 🔴 Сложный
▶
Глагол %w оборачивает ошибку, сохраняя цепочку. errors.Is рекурсивно разворачивает обёртки и сравнивает с целевой ошибкой. Обычное == не сработало бы, потому что err - другой объект. errors.Is создан именно для обёрнутых ошибок.
Подробнее →fmt.Errorf("%w и %w", err1, err2) (Go 1.20+)? 🔴 Сложный
▶
Go 1.20 позволяет оборачивать несколько ошибок через несколько %w в fmt.Errorf. Результат реализует interface{ Unwrap() []error }. errors.Is и errors.As проверяют все обёрнутые ошибки.
Подробнее →