Материал проходит вычитку — возможны неточности.
Урок 51 из 118

Стратегия уровней

Миша и Аня поспорили, на каком уровне оборачивать ошибки: внизу, в середине или наверху. Аня нарисовала схему из трёх этажей и сразу оговорилась, что это стратегия, а не закон. Спор закончился общей договорённостью команды.

Главная мысль

у каждого уровня программы своя работа с ошибками: нижний — сентинелы, средний — оборачивание контекстом через %w, верхний — различение через Is/As. Это распространённая стратегия, а не закон языка.

Нижний уровень — сентинелы

Пакет, работающий с хранилищем, определяет эталоны своих сбоев и возвращает их напрямую:

var ErrNotFound = errors.New("файл не найден")

func Get(id string) (FileMeta, error) {
    // ...
    return FileMeta{}, ErrNotFound
}

Здесь ещё нет контекста: пакет не знает, кто и зачем его вызывает.

Средний уровень — оборачивание

Сервисный слой добавляет контекст, не теряя причину:

f, err := repo.Get(id)
if err != nil {
    return fmt.Errorf("получить файл %s: %w", id, err)
}

Каждый уровень дописывает свой кусок: «получить файл report.pdf: запрос к хранилищу: файл не найден». Итоговая строка — читаемая история пути ошибки снизу вверх.

Верхний уровень — различение

HTTP-обработчик решает, что ответить, по причине:

f, err := svc.GetFile(id)
if err != nil {
    if errors.Is(err, repo.ErrNotFound) {
        w.WriteHeader(http.StatusNotFound)
        return
    }
    w.WriteHeader(http.StatusInternalServerError)
    return
}

Обработчик не парсит текст ошибки — он использует Is/As по цепочке. Это и есть стратегия: внизу создают и возвращают, в середине оборачивают, наверху различают.

Границы между уровнями не жёсткие: оборачивание уместно и на нижнем уровне — например, вокруг сентинела драйвера БД или ошибки внешней библиотеки. Схема — удобный ориентир, а не правило, за нарушение которого полагается выговор.

В следующем уроке

Вы узнаете:

  • где и как логировать цепочку ошибок
  • как %+v печатает полный стек в исторических библиотеках
Задание · вопросы

Проверьте себя

Вопрос 1 из 3

На верхнем уровне нужно отличить «файл не найден» от «БД недоступна». Что использовать?

Вопрос 2 из 3

Какие роли у уровней программы в стратегии ошибок?

Вопрос 3 из 3

Чем плох strings.Contains(err.Error(), "not found")?

Итоги

Нижний уровень — сентинелы; средний — %w-контекст; верхний — Is/As. Схема — стратегия, а не закон: оборачивание в repo допустимо. Ошибка — это интерфейс, по которому общаются уровни, а не строка для печати.

Наш сайт собирает куки. Чтобы тебе было удобнее им пользоваться. Нажимая на кнопку, ты даёшь разрешение собирать куки