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

error — это интерфейс

«Файл не найден» долго был просто строкой, и сравнения по тексту начали сыпаться. Миша завёл в хранилище одну общую ошибку ErrNotFound, на которую можно ссылаться из любого слоя.

Главная мысль

error — встроенный интерфейс с одним методом Error string; ошибки создают через errors.New и fmt.Errorf, а для сравнения — сентинелы-переменные.

Тип error

Go

Это и есть весь тип error, предопределённый в языке. Любой тип с методом Error string — это ошибка. Поскольку error — интерфейс, к нему применима вся модель из прошлых уроков, включая ловушку typed nil.

Создание

err := errors.New("файл не найден")

err = fmt.Errorf("не удалось открыть %s: %v", path, err)

errors.New — для фиксированного текста, fmt.Errorf — с форматированием. Второй пример пока ущербный: %v теряет связь с исходной ошибкой — об этом следующий урок.

Сентинелы

var ErrNotFound = errors.New("файл не найден")

if errors.Is(err, ErrNotFound) {
    // ...
}

Сентинел — переменная-ошибка уровня пакета, эталон «такой-то сбой». Сравнение через == работает, только когда ошибки не оборачиваются (урок покажет errors.Is). Сентинелы уместны для ошибок, на которые вызывающий должен реагировать по-разному.

В следующем уроке

Вы узнаете:

  • как устроены собственные типы ошибок с полями
  • почему сентинелы называют ErrXxx, а не XxxError
<!-- wp:course-hub/quiz {"title":"Проверьте себя","questions":[{"text":"err := get() вернул typed nil (*MyErr)(nil). Что произойдёт при err.Error()?","options":[{"text":"Паника — nil pointer dereference: прямой вызов Error() вне fmt паникует на nil-получателе","correct":true,"comment":"fmt.Println(err) при этом печатает : fmt вызывает Error(), перехватывает панику. Методы ошибок должны иметь nil-проверку."},{"text":"Вернёт пустую строку","correct":false},{"text":"Вернёт \"ошибка 0\"","correct":false},{"text":"Ошибка компиляции","correct":false}]},{"text":"Что такое error в Go?","options":[{"text":"Интерфейс с одним методом Error() string","correct":true,"comment":"Любой тип с методом Error() string — это ошибка; поэтому к error применима вся модель интерфейсов."},{"text":"Класс с полем-сообщением","correct":false},{"text":"Строка с кодом ошибки","correct":false},{"text":"Перечисление кодов","correct":false}]},{"text":"Что такое сентинел-ошибка?","options":[{"text":"Переменная-ошибка уровня пакета — эталон «такой-то сбой» для сравнения","correct":true,"comment":"Сравнение через == работает только для необёрнутых ошибок; сентинелы уместны, когда вызывающий реагирует по-разному."},{"text":"Ошибка с полем-строкой","correct":false},{"text":"Любая ошибка из fmt.Errorf","correct":false},{"text":"Ошибка, обёрнутая через %w","correct":false}]}]} /-->
Итоги

error — интерфейс с одним методом. Создание — errors.New/fmt.Errorf; эталоны для сравнения — сентинелы. Дальше — оборачивание.

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