%wВ Go 1.13 появился
%w, который сохраняет исходную ошибку внутри обёртки и позволяет проверять её дальше по коду через errors.Is и errors.As.Когда ошибка проходит через несколько слоёв приложения, на каждом уровне к ней добавляют контекст. Если при этом теряется исходный тип, наверху остаётся только текст, и проверить причину можно лишь по подстроке. Любая правка формулировки ломает такую проверку.
Старый способ:
fmt.Errorf("failed to fetch user: %v", err)%v подставляет текст ошибки и выбрасывает сам объект. Узнать, что под капотом лежала sql.ErrNoRows, после этого уже нельзя.Современный способ:
fmt.Errorf("failed to fetch user: %w", err)%w оборачивает ошибку и сохраняет ссылку на оригинал, поэтому цепочку потом можно размотать.Как проверять причину
errors.Is идёт по всей цепочке обёрток и сравнивает каждое звено с конкретным значением:if errors.Is(err, sql.ErrNoRows) {
// пользователь не найден
}Не важно, сколько слоёв обёрток сверху, проверка доберётся до нужной ошибки.
Когда нужен сам объект
Если требуется не просто факт совпадения, а доступ к полям ошибки, помогает
errors.As. Он находит в цепочке ошибку нужного типа и записывает её в переменную:var pathErr *os.PathError
if errors.As(err, &pathErr) {
slog.Error("ошибка пути", "path", pathErr.Path)
}
Своя ошибка в цепочке
Чтобы ваш тип распознавался через
errors.Is и errors.As, достаточно реализовать метод Unwrap:type AppError struct {
Code int
Err error
}
func (e *AppError) Unwrap() error { return e.Err }%w заменил хрупкое сравнение строк на надёжную проверку по значению и по типу. Оборачивайте ошибки этим глаголом везде, где добавляете контекст, и используйте errors.Is вместо сравнения текста.📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoToProduction