Перейти до основного вмісту
Модуль 2 · Урок 5 із 510/50 у курсі~12 min
Модульні уроки (5/5)

Помилки: шаблон `if err != nil`

У Go помилки є значеннями, а не винятками. Функція, яка може fail повертає помилку як останнє значення, і абонент перевіряє її явно. Це чітко, передбачувано, легко перевірити — ціна є трохи більше багатослівності.

Інтерфейс error

error — це невеликий інтерфейс, вбудований у мову:

Go
type error interface {
    Error() string
}

Будь-який тип, який реалізує Error() string, є error.

Фундаментальна закономірність

Go
v, err := operazione()
if err != nil {
    // gestisci o propaga
    return err
}
// usa v

Ви побачите це тисячі разів: це ідіоматичний код для кожного помилковий виклик. Не відчувайте провини за повторення — це особливість, а не помилка.

Помилки збірки: errors.New та fmt.Errorf

Go
import (
    "errors"
    "fmt"
)

err1 := errors.New("file mancante")
err2 := fmt.Errorf("apertura %q fallita: permesso negato", path)

fmt.Errorf ідеально підходить, якщо ви хочете включити змінні в повідомлення.

Обгортка з %w

Щоб поширити помилку додавання контексту БЕЗ втрати оригіналу:

Go
f, err := os.Open(path)
if err != nil {
    return fmt.Errorf("config: %w", err)
}

%w "загортає" вихідну помилку, яку можна виправити пізніше за допомогою errors.Is (рівність для дозорних) або errors.As (для конкретного типу):

Go
if errors.Is(err, os.ErrNotExist) {
    // file inesistente, gestione speciale
}

Дозорні помилки

Це помилки, експортовані як змінні, які використовуються для порівняння з errors.Is:

Go
var ErrNotFound = errors.New("non trovato")

func find(id int) (Item, error) {
    // ...
    return Item{}, ErrNotFound
}

// chiamante:
if errors.Is(err, ErrNotFound) { ... }

panic та recover (попередній перегляд)

panic існує в Go, але зарезервовано для невиправних помилок (наприклад, помилки, порушені інваріанти), не для нормального потоку керування. Ми підемо глибше модуль Функції з defer/recover. Наразі: не використовуйте його на місці шаблону if err != nil.

Спробуйте

вправи#go.m2.l5.e1
Спроби: 0Завантаження…

Обробка помилки з strconv.Atoi: якщо err != nil, вивести її та повернути; інакше надрукувати n.

Завантаження редактора…
Показати підказку

Канонічний шаблон: перевірте `err != nil`, log/return, потім використовуйте `n`.

Рішення доступне після 3 спроб

вправи#go.m2.l5.e2
Спроби: 0Завантаження…

Реалізація safeDiv: if b == 0 повертає 0 і errors.New('divisione per zero'); інакше a/b і нуль.

Завантаження редактора…
Показати підказку

Перевірте `b == 0` ПЕРЕД поділом, щоб уникнути паніки під час виконання.

Рішення доступне після 3 спроб

Quiz#go.m2.l5.e3
Готовий

Який ідіоматичний шаблон обробки помилок у Go?

Go
v, err := f()
// poi?
Варіанти відповідей

Підведення підсумків

  • error — це інтерфейс з одним методом Error() string.
  • Канонічний шаблон: v, err := f(); if err != nil { return err }.
  • Помилки збірки з errors.New(msg) або fmt.Errorf("ctx: %w", err).
  • Використовуйте %w для обмотування та errors.Is / errors.As для перевірки ланцюга.
  • panic лише для невиправних помилок, НЕ для звичайного потоку керування.