Уроки модуля (5/5)
Ошибки: шаблон `if err != nil`
В Go ошибки — это значения, а не исключения. Функция, которая может error возвращает ошибку как последнее значение, и вызывающая сторона проверяет ее. явно. Это явно, предсказуемо, легко тестируется — цена немного больше многословия.
Интерфейс error
error — небольшой интерфейс, встроенный в язык:
type error interface {
Error() string
}Любой тип, реализующий Error() string, является error.
Фундаментальный шаблон
v, err := operazione()
if err != nil {
// gestisci o propaga
return err
}
// usa vВы увидите это тысячи раз: это идиоматический код для каждого ошибочный звонок. Не чувствуйте вины за повторение — это особенность, а не ошибка.
Ошибки сборки: errors.New и fmt.Errorf.
import (
"errors"
"fmt"
)
err1 := errors.New("file mancante")
err2 := fmt.Errorf("apertura %q fallita: permesso negato", path)fmt.Errorf идеально подходит, если вы хотите включить в сообщение переменные.
Обертывание с помощью %w
Чтобы распространить ошибку добавления контекста БЕЗ потери оригинала:
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("config: %w", err)
}%w «обертывает» исходную ошибку, которую можно исправить позже с помощью
errors.Is (равенство для дозорных) или errors.As (для конкретного типа):
if errors.Is(err, os.ErrNotExist) {
// file inesistente, gestione speciale
}Дозорные ошибки
Это ошибки, экспортированные как переменные, используемые для сравнения с errors.Is:
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.
Попробуйте это
Обработка ошибки из strconv.Atoi: если err != nil, выведите ее и верните результат; в противном случае выведите n.
Показать подсказку
Канонический шаблон: проверьте `err != nil`, log/return, затем используйте `n`.
Решение доступно после 3 попыток
Реализуйте SafeDiv: если b == 0, верните 0 и error.New('divisione на ноль'); в противном случае a/b и ноль.
Показать подсказку
Проверьте `b == 0` ПЕРЕД делением, чтобы избежать паники во время выполнения.
Решение доступно после 3 попыток
Какой идиоматический шаблон обработки ошибки в 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только для неисправимых ошибок, НЕ для нормального потока управления.