Оборачивание через %w
ErrNotFound прижился, но в логах отовсюду торчало голое «not found»: было непонятно, какой шаг потерял файл. Миша завернул ошибку в контекст так, чтобы причина не потерялась.
%w в fmt.Errorf оборачивает ошибку, сохраняя цепочку причин; %v цепочку обрывает.
%w строит цепочку
func loadMeta(path string) error {
data, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("не удалось прочитать файл: %w", err)
}
// ...
}
%w заворачивает исходную ошибку внутрь новой: новая ошибка — текст с контекстом, а внутри — причина. Уровни добавляют контекст, не теряя исходник: «не удалось прочитать файл: открыть report.pdf: файл не существует».
%v обрывает связь
return fmt.Errorf("не удалось прочитать файл: %v", err)
%v просто печатает текст ошибки внутрь новой. Получается строка, а не цепочка: исходную ошибку внутри уже не найти — errors.Is и errors.As (следующий урок) не увидят причину.
Зачем цепочка
if errors.Is(err, fs.ErrNotExist) {
// файла нет — создаём дефолтную запись
}
Вызывающий различает причины сквозь всю глубину контекста: наверху он видит длинную цепочку, но по errors.Is понимает — где-то внизу fs.ErrNotExist, а значит, файла нет и можно завести дефолтную запись. Без цепочки пришлось бы сравнивать строки или тащить тип ошибки через все уровни.
Вы узнаете:
- как
errors.Joinобъединяет несколько причин - как написать собственный
Unwrap()для типа ошибки
Проверьте себя
Что делает %w в fmt.Errorf?
Что делает %v в fmt.Errorf?
Как errors.Is находит причину сквозь обёртки?
правильных ответов
%w — обернуть с сохранением причины; %v — просто напечатать текст. Цепочка — то, что позволяет верхнему уровню различать причины.
10 000 ₽ · 60 минут · онлайн