TGViewer
Всё о разработке | Леонид Ченский Всё о разработке | Леонид Ченский @leoscode · 732 subscribers
Post #122 1.54K
ИЗЯЩНАЯ РАБОТА С ОШИБКАМИ В GO, ИЛИ КАК ИХ СРАВНИВАТЬ

Обычное err == myErr в Go работает не всегда так, как ты ожидаешь. Особенно если ты оборачиваешь ошибку через fmt.Errorf("context: %w", err). В таких случаях Go предоставляет более мощные инструменты — errors.Is и errors.As.

❓Как работает errors.Is

Когда ты используешь %w в fmt.Errorf (врапинг ошибки), ты как бы упаковываешь одну ошибку внутрь другой, добавляя контекст. errors.Is умеет разворачивать такие обёртки и проверять, есть ли внутри нужная ошибка:

var ErrNotFound = errors.New("not found")
err := fmt.Errorf("ошибка в поиске: %w", ErrNotFound)

if errors.Is(err, ErrNotFound) {
fmt.Println("Ничего не найдено")
}


Под капотом errors.Is делает так: если ошибка обёрнута через %w, она вызывает Unwrap() и идёт по цепочке, пока не найдёт нужную. Если ты просто сравнишь err == ErrNotFound, то получишь false, потому что это уже не тот же объект — он обёрнут.

❓А что делает errors.As

Иногда нужно не просто узнать, была ли ошибка определённого типа, но и получить доступ к её полям. Например:
type MyError struct {
Code int
Msg string
}

func (e *MyError) Error() string {
return fmt.Sprintf("code: %d, msg: %s", e.Code, e.Msg)
}

err := &MyError{Code: 499, Msg: "custom"}
var myErr *MyError

if errors.As(err, &myErr) {
fmt.Println("У нас ошибка кода", myErr.Code)
}


Ты можешь доставать полезные данные из ошибки, если она реализует нужный тип. Это особенно удобно, когда у тебя есть логика, завязанная на тип ошибки (например, логирование по коду, трассировка и т.д.).

❓Как кастомизировать сравнение — метод Is()

Ты даже можешь сам определить, когда твоя ошибка считается «равной» другой. Для этого нужно реализовать метод Is(target error) в своей реализации:
type HttpError struct {
Code int
Msg string
}

func (e *HttpError) Error() string {
return fmt.Sprintf("HTTP %d: %s", e.Code, e.Msg)
}

func (e *HttpError) Is(target error) bool {
t, ok := target.(*HttpError)
return ok && e.Code == t.Code
}


Теперь, даже если сообщения об ошибках разные, но коды совпадают — errors.Is вернёт true:
var Err404 = &HttpError{Code: 404}
err := fmt.Errorf("обёрнутая ошибка: %w", &HttpError{Code: 404, Msg: "page not found"})

if errors.Is(err, Err404) {
fmt.Println("Обнаружена 404")
}


❓Когда и где это реально нужно (примеры из практики)

— В библиотеках: ты возвращаешь ошибки вроде ErrInvalidConfig или ErrNotConnected, и хочешь, чтобы пользователи могли их отловить независимо от контекста

— В сервисах: API может возвращать ошибки с кодами, а внутри тебе удобно описывать их кастомными типами — и потом ловить их по errors.Is

— В middleware: например, хочешь логировать всё, кроме ErrUnauthorized — тогда errors.Is(err, ErrUnauthorized) спасёт от лишнего шума

— В gRPC/HTTP-хендлерах: удобно классифицировать ошибки и автоматически подставлять нужный статус код в ответе

— В CLI-инструментах: логика выхода с кодами ошибок может зависеть от типа ошибки, а не только от текста

Если ты до сих пор сравниваешь ошибки через ==, самое время освоить errors.Is и errors.As. Это делает твой код гибким, читаемым и гораздо ближе к надёжной архитектуре. Go даёт тебе все инструменты — просто используй их.

Больше примеров работы с ошибками даю в бесплатном уроке на своем курсе Go!

P.S. все еще действует промокод на скидку 30% - FEIN
  • 👍 12
  • ❤ 7
  • ⚡ 3
  • 👏 2
  • 🔥 1
More from @leoscode
  1. Sep 15, 2026Помню как в детстве хотел такого же ассистента как Jarvis у Железного человека. Сейчас буд…
  2. Aug 24, 2026Гипотетическая история Представьте завтра все датацентры «вдруг» перестанут работать. Прив…
  3. Aug 4, 2026"Капризный день"
  4. Jul 17, 2026Пользуюсь случаем, напишу тут: ищу заряжененного Go разработчика к себе в команду. Ссылка…
  5. Jul 14, 2026Утро вторника началось не с кофе… Кто положил, признавайтесь!)
  6. Jul 1, 2026Согласны? 👍 Да 🗿Нет
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →