Что такое wrapped errors и зачем нужны fmt.Errorf("%w"), errors.Is, errors.As
1️⃣ Как кратко ответить
Wrapped errors в Go позволяют оборачивать ошибки для сохранения контекста и цепочки ошибок. Функция fmt.Errorf("%w", err) используется для оборачивания ошибок, errors.Is — для проверки, является ли ошибка конкретной ошибкой в цепочке, а errors.As — для извлечения конкретного типа ошибки из цепочки.
2️⃣ Подробное объяснение темы
В Go обработка ошибок является важной частью программирования. Wrapped errors (обернутые ошибки) позволяют добавлять контекст к ошибкам, сохраняя при этом оригинальную ошибку. Это полезно для отладки и понимания того, что именно пошло не так в программе.
Зачем нужны wrapped errors?
Когда в программе возникает ошибка, важно не только знать, что она произошла, но и понимать, в каком контексте это случилось. Например, если функция не смогла открыть файл, полезно знать, какой именно файл и почему. Обернутые ошибки позволяют добавлять такую информацию, сохраняя при этом оригинальную ошибку.
Как работают wrapped errors?
В Go для оборачивания ошибок используется функция fmt.Errorf с форматом %w. Это позволяет создать новую ошибку, которая содержит оригинальную ошибку и дополнительный контекст.
package main
import (
"errors"
"fmt"
"os"
)
func main() {
_, err := os.Open("nonexistentfile.txt")
if err != nil {
// Оборачиваем ошибку, добавляя контекст
wrappedErr := fmt.Errorf("failed to open file: %w", err)
fmt.Println(wrappedErr)
}
}
os.Open("nonexistentfile.txt"): Пытается открыть несуществующий файл, возвращая ошибку.fmt.Errorf("failed to open file: %w", err): Создает новую ошибку, оборачивая оригинальную ошибкуerrи добавляя контекст "failed to open file".
Использование errors.Is
Функция errors.Is позволяет проверить, является ли ошибка конкретной ошибкой в цепочке обернутых ошибок. Это полезно, когда нужно определить, произошла ли конкретная ошибка, независимо от того, сколько раз она была обернута.
package main
import (
"errors"
"fmt"
"os"
)
func main() {
_, err := os.Open("nonexistentfile.txt")
if err != nil {
wrappedErr := fmt.Errorf("failed to open file: %w", err)
if errors.Is(wrappedErr, os.ErrNotExist) {
fmt.Println("File does not exist")
}
}
}
errors.Is(wrappedErr, os.ErrNotExist): Проверяет, является лиwrappedErrошибкойos.ErrNotExist, даже если она обернута.
Использование errors.As
Функция errors.As позволяет извлечь конкретный тип ошибки из цепочки обернутых ошибок. Это полезно, когда нужно работать с конкретным типом ошибки, например, для получения дополнительных данных.
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
)
func main() {
_, err := os.Open("nonexistentfile.txt")
if err != nil {
wrappedErr := fmt.Errorf("failed to open file: %w", err)
var pathError *os.PathError
if errors.As(wrappedErr, &pathError) {
fmt.Printf("Path error: %v\n", pathError.Path)
}
}
}
var pathError *os.PathError: Объявляет переменную для хранения ошибки типа*os.PathError.errors.As(wrappedErr, &pathError): Извлекает ошибку типа*os.PathErrorизwrappedErr, если она присутствует.
Заключение
Wrapped errors и функции fmt.Errorf("%w"), errors.Is, errors.As предоставляют мощные инструменты для работы с ошибками в Go, позволяя добавлять контекст, проверять и извлекать ошибки из цепочки. Это делает обработку ошибок более гибкой и информативной.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться