Перейти к основному содержимому
Модуль 2 · Урок 5 из 510/50 в курсе~12 min
Уроки модуля (5/5)

Ошибки: шаблон `if err != nil`

В Go ошибки — это значения, а не исключения. Функция, которая может error возвращает ошибку как последнее значение, и вызывающая сторона проверяет ее. явно. Это явно, предсказуемо, легко тестируется — цена немного больше многословия.

Интерфейс error

error — небольшой интерфейс, встроенный в язык:

Go
type error interface {
    Error() string
}

Любой тип, реализующий Error() string, является error.

Фундаментальный шаблон

Go
v, err := operazione()
if err != nil {
    // gestisci o propaga
    return err
}
// usa v

Вы увидите это тысячи раз: это идиоматический код для каждого ошибочный звонок. Не чувствуйте вины за повторение — это особенность, а не ошибка.

Ошибки сборки: errors.New и fmt.Errorf.

Go
import (
    "errors"
    "fmt"
)

err1 := errors.New("file mancante")
err2 := fmt.Errorf("apertura %q fallita: permesso negato", path)

fmt.Errorf идеально подходит, если вы хотите включить в сообщение переменные.

Обертывание с помощью %w

Чтобы распространить ошибку добавления контекста БЕЗ потери оригинала:

Go
f, err := os.Open(path)
if err != nil {
    return fmt.Errorf("config: %w", err)
}

%w «обертывает» исходную ошибку, которую можно исправить позже с помощью errors.Is (равенство для дозорных) или errors.As (для конкретного типа):

Go
if errors.Is(err, os.ErrNotExist) {
    // file inesistente, gestione speciale
}

Дозорные ошибки

Это ошибки, экспортированные как переменные, используемые для сравнения с errors.Is:

Go
var ErrNotFound = errors.New("non trovato")

func find(id int) (Item, error) {
    // ...
    return Item{}, ErrNotFound
}

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

panic и recover (предварительная версия)

panic существует в Go, но зарезервирован для неустранимых ошибок (например, ошибок, нарушенные инварианты), а не для нормального потока управления. Мы пойдем глубже в модуль функций с defer/recover. На данный момент: не используйте на месте шаблона if err != nil.

Попробуйте это

Упражнение#go.m2.l5.e1
Попыток: 0Загрузка…

Обработка ошибки из strconv.Atoi: если err != nil, выведите ее и верните результат; в противном случае выведите n.

Загрузка редактора…
Показать подсказку

Канонический шаблон: проверьте `err != nil`, log/return, затем используйте `n`.

Решение доступно после 3 попыток

Упражнение#go.m2.l5.e2
Попыток: 0Загрузка…

Реализуйте SafeDiv: если b == 0, верните 0 и error.New('divisione на ноль'); в противном случае a/b и ноль.

Загрузка редактора…
Показать подсказку

Проверьте `b == 0` ПЕРЕД делением, чтобы избежать паники во время выполнения.

Решение доступно после 3 попыток

Quiz#go.m2.l5.e3
Готово

Какой идиоматический шаблон обработки ошибки в Go?

Go
v, err := f()
// poi?
Варианты ответа

Резюме

  • error — это интерфейс с одним методом Error() string.
  • Канонический шаблон: v, err := f(); if err != nil { return err }.
  • Ошибки сборки с errors.New(msg) или fmt.Errorf("ctx: %w", err).
  • Используйте %w для упаковки и errors.Is / errors.As для проверки цепочки.
  • panic только для неисправимых ошибок, НЕ для нормального потока управления.