⚠️ Обработка ошибок в Go
Обработка ошибок - фундаментальная часть Go. В языке нет исключений, вместо этого ошибки возвращаются как последнее возвращаемое значение функций. Это делает логику ошибок явной, понятной и предсказуемой.
📌 Основные принципы
- Ошибки возвращаются последним значением функции.
- Если ошибки нет - возвращается
nil. - Ошибка - это значение, реализующее интерфейс:
type error interface {
Error() string
}
Это делает ошибки обычными значениями, с которыми можно работать.
🛠 Простые ошибки через errors.New
Стандартный пакет errors позволяет быстро создавать простые ошибки:
import "errors"
func divide(lhs, rhs int) (int, error) {
if rhs == 0 {
return 0, errors.New("cannot divide by zero")
}
return lhs / rhs, nil
}
Такой подход удобен, когда ошибка не требует сложных данных.
🧩 Создание собственных ошибок
Можно создавать собственные типы ошибок:
type DivError struct {
a, b int
}
func (d *DivError) Error() string {
return fmt.Sprintf("Cannot divide by zero: %d / %d", d.a, d.b)
}
Почему метод должен быть с указателем?
- Чтобы корректно сравнивать ошибки.
- Чтобы избежать копирования структуры ошибки.
▶️ Использование кастомной ошибки
func div(a, b int) (int, error) {
if b == 0 {
return 0, &DivError{a, b}
}
return a / b, nil
}
answer, err := div(9, 0)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(answer)
🔍 Работа с ошибками: errors.Is
Когда нужно проверить, относится ли ошибка к определённому типу:
var inputErr = &UserError{"Input Error"}
if errors.Is(err, inputErr) {
fmt.Println("Input error:", err)
} else {
fmt.Println("Other error:", err)
}
errors.Is проверяет всю цепочку ошибок, включая обёртки.
🔎 Извлечение ошибки: errors.As
Когда нужно получить объект ошибки конкретного типа:
var target *UserError
if errors.As(err, &target) {
fmt.Println("User error:", target)
} else {
fmt.Println("Other error:", err)
}
Если ошибка соответствует типу, она будет извлечена в переменную
target.
📘 Итоги
- Ошибки возвращаются последним значением, нет исключений.
- Простые ошибки создаются через
errors.New. - Кастомные ошибки реализуют интерфейс
error. - Всегда проверяйте
if err != nil. errors.Is- для проверки типа ошибки.errors.As- для извлечения ошибки нужного типа.