РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
492 of 1593 menu

Обёртывание ошибок

Обёртывание ошибок (error wrapping) в Go — это техника, позволяющая добавлять дополнительный контекст к существующей ошибке, создавая цепочку из вложенных ошибок. Это особенно полезно для передачи информации о том, где и при каких обстоятельствах произошла ошибка, без потери исходной ошибки. Основная цель обёртывания — сохранение возможности проверки исходной ошибки с помощью функций errors.Is и errors.As, даже после добавления контекста.

В Go обёртывание ошибок выполняется с помощью оператора %w в функции fmt.Errorf или с использованием функции errors.Join. Обёрнутая ошибка сохраняет связь с исходной, что позволяет программе проверять, является ли ошибка конкретным типом, или соответствует ли она определённому значению. Основное преимущество обёртывания — возможность добавления контекста (например, имени функции, идентификатора запроса или параметров) без изменения исходной ошибки.

Синтаксис

err := fmt.Errorf("context: %w", originalErr)

В данном примере %w — это специальный форматный вербайзер, который оборачивает ошибку originalErr в новую ошибку с добавленным текстом "context:".

Пример создания обёрнутой ошибки

Рассмотрим пример, где мы оборачиваем ошибку, полученную при попытке открыть файл, добавляя информацию о том, что это произошло при загрузке конфигурации:

package main import ( "fmt" "os" ) func loadConfig() error { _, err := os.Open("config.json") if err != nil { return fmt.Errorf("load config failed: %w", err) } return nil } func main() { err := loadConfig() if err != nil { fmt.Println(err) } }

Результат выполнения кода будет содержать как добавленный контекст, так и исходную ошибку:

"load config failed: open config.json: no such file or directory"

Проверка обёрнутой ошибки с помощью errors.Is

Обёрнутые ошибки можно проверять на соответствие определённому типу или значению с помощью функции errors.Is. Это позволяет обрабатывать ошибки на разных уровнях, не теряя информации о её происхождении:

package main import ( "errors" "fmt" "os" ) var ErrNotFound = errors.New("file not found") func loadConfig() error { _, err := os.Open("config.json") if errors.Is(err, os.ErrNotExist) { return fmt.Errorf("load config failed: %w", ErrNotFound) } return err } func main() { err := loadConfig() if errors.Is(err, ErrNotFound) { fmt.Println("Configuration file is missing") } else if err != nil { fmt.Println("Other error:", err) } }

Результат выполнения кода:

"Configuration file is missing"

Обёртывание с помощью errors.Join

Начиная с Go 1.20, появилась функция errors.Join, которая позволяет объединять несколько ошибок в одну, оборачивая их все одновременно. Это удобно, когда требуется собрать несколько ошибок в одну цепочку:

package main import ( "errors" "fmt" ) func main() { err1 := errors.New("database connection failed") err2 := errors.New("cache read error") wrapped := errors.Join(err1, err2) fmt.Println(wrapped) }

Результат выполнения кода:

"database connection failed\ncache read error"

В этом примере обе ошибки объединяются в одну, и их можно обрабатывать совместно. Однако, в отличие от fmt.Errorf с %w, errors.Join не добавляет текстовый контекст, а просто объединяет несколько ошибок в одну структуру.

Смотрите также

  • функцию errors.Is,
    которая проверяет, содержит ли цепочка ошибок конкретную ошибку
  • функцию errors.As,
    которая извлекает ошибку определённого типа из цепочки
  • функцию errors.Unwrap,
    которая возвращает предыдущую ошибку в цепочке
  • функцию fmt.Errorf,
    которая форматирует строку и может обёртывать ошибки через %w
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить