Ответ
В Go для ошибок существует встроенный стандартный интерфейс error
:
// Встроенный интерфейс error
type error interface {
Error() string
}
Любой тип, который реализует метод Error() string
, автоматически удовлетворяет этому интерфейсу. Это позволяет создавать кастомные типы ошибок с дополнительными полями и методами.
Создание ошибок:
-
Простые ошибки создаются с помощью пакета
errors
илиfmt
:import ( "errors" "fmt" ) // C помощью errors.New err1 := errors.New("произошла стандартная ошибка") // C помощью fmt.Errorf для форматирования err2 := fmt.Errorf("ошибка пользователя %d", userID)
-
Кастомные типы ошибок для добавления контекста:
type MyError struct { StatusCode int Message string } func (e *MyError) Error() string { return fmt.Sprintf("статус: %d, сообщение: %s", e.StatusCode, e.Message) } func doRequest() error { return &MyError{StatusCode: 500, Message: "внутренняя ошибка сервера"} }
Обработка ошибок (Go 1.13+):
С версии Go 1.13 пакет errors
был расширен функциями для работы с цепочками ошибок (error wrapping):
errors.Unwrap(err error) error
: Позволяет извлечь "внутреннюю" ошибку из обертки.errors.Is(err, target error) bool
: Проверяет, есть ли в цепочке ошибокerr
ошибка, эквивалентнаяtarget
.errors.As(err error, target interface{}) bool
: Проверяет, есть ли в цепочкеerr
ошибка, которую можно привести к типуtarget
, и если да, присваивает ееtarget
.
// Пример использования errors.As
var myErr *MyError
if err := doRequest(); errors.As(err, &myErr) {
fmt.Printf("Получена кастомная ошибка со статусом: %dn", myErr.StatusCode)
}