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

Is и As

Кто-то сравнил ошибки по тексту, и после добавления контекста проверки замолчали. Клиент запрашивал несуществующий файл и получал 500 вместо 404. Миша перевёл различение ошибок на поиск по всей цепочке.

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

errors.Is ищет ошибку по значению (сентинел), errors.As — по типу, и обе проходят по всей цепочке оборачивания.

Is — по значению

if errors.Is(err, ErrNotFound) {
    // где-то в цепочке есть ErrNotFound
}

Is разворачивает цепочку и сравнивает каждый слой с целевой ошибкой. Для обычных сентинелов это ==, но типы ошибок могут определять свой Is — например, сравнивать по коду ошибки, а не по указателю.

As — по типу

var pathErr *fs.PathError
if errors.As(err, &pathErr) {
    fmt.Println(pathErr.Path) // доступ к полям конкретного типа
}

As ищет в цепочке ошибку нужного типа и, если нашёл, кладёт её в pathErr. Заметь, что передаётся указатель на указатель: As присваивает через него. As паникует, если целевая переменная — не указатель на ошибку или интерфейс.

Is против ==

Почему не err == ErrNotFound? Потому что == смотрит только верхний слой — а там обычно обёртка с контекстом. Is пробивает всю цепочку:

wrapped := fmt.Errorf("контекст: %w", ErrNotFound)
fmt.Println(wrapped == ErrNotFound)      // false
fmt.Println(errors.Is(wrapped, ErrNotFound)) // true
В следующем уроке

Вы узнаете:

  • как написать пользовательские Is и As для ошибок с полями
  • как errors.Join взаимодействует с Is и As
Задание · вопросы

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

Вопрос 1 из 3

wrapped := fmt.Errorf("запрос к БД: %w", ErrNotFound). Чему равны wrapped == ErrNotFound и errors.Is(wrapped, ErrNotFound)?

Вопрос 2 из 3

var s string; errors.As(err, s). Что произойдёт?

Вопрос 3 из 3

Чем errors.Is отличается от errors.As?

Итоги

Is — «есть ли в цепочке эта ошибка по значению»; As — «есть ли в цепочке ошибка такого типа». Обе идут сквозь %w-обёртки.

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