ENIGMA AI
ENIGMA AI
Go Средний

Как принято обрабатывать ошибки в Go?

Обработка ошибок в Go

Базовый паттерн:

result, err := doSomething()
if err != nil {
    return fmt.Errorf("doSomething failed: %w", err)
}
// Используем result

Создание ошибок:

// Простая ошибка
err := errors.New("something went wrong")

// Форматированная ошибка
err := fmt.Errorf("user %d not found", userID)

// Обёртка (сохраняет оригинал)
err := fmt.Errorf("database error: %w", originalErr)

Проверка типа ошибки:

errors.Is() — проверка значения:

if errors.Is(err, sql.ErrNoRows) {
    // Обработка "не найдено"
}

// Работает с wrapped errors

errors.As() — проверка типа:

var pathError *os.PathError
if errors.As(err, &pathError) {
    fmt.Println("Path:", pathError.Path)
}

Sentinel Errors:

var (
    ErrNotFound = errors.New("not found")
    ErrInvalid  = errors.New("invalid input")
)

func FindUser(id int) (*User, error) {
    if id <= 0 {
        return nil, ErrInvalid
    }
    // ...
    return nil, ErrNotFound
}

Custom Error Types:

type ValidationError struct {
    Field   string
    Message string
}

func (e ValidationError) Error() string {
    return fmt.Sprintf("%s: %s", e.Field, e.Message)
}

// Использование
return ValidationError{
    Field:   "email",
    Message: "invalid format",
}

Wrapping для контекста:

func GetUser(id int) (*User, error) {
    user, err := db.FindUser(id)
    if err != nil {
        return nil, fmt.Errorf("GetUser(%d): %w", id, err)
    }
    return user, nil
}

Паттерн defer для cleanup:

func processFile(path string) (err error) {
    f, err := os.Open(path)
    if err != nil {
        return err
    }
    defer func() {
        if cerr := f.Close(); cerr != nil && err == nil {
            err = cerr
        }
    }()

    // Работа с файлом
    return nil
}

Anti-patterns:

// ПЛОХО: игнорирование ошибки
result, _ := doSomething()

// ПЛОХО: panic для обычных ошибок
if err != nil {
    panic(err)
}

// ПЛОХО: строковое сравнение
if err.Error() == "not found" { }

// ХОРОШО: используйте errors.Is/As

Best Practices:

  1. Всегда проверяйте ошибки
  2. Добавляйте контекст при обёртке
  3. Используйте %w для unwrap
  4. Определяйте sentinel errors для API
  5. panic только для программных ошибок

Похожие вопросы

Готовитесь к собеседованию?

ENIGMA AI — невидимый ИИ-помощник для технических интервью

Попробовать бесплатно
Все вопросы