Стратегия уровней
Миша и Аня поспорили, на каком уровне оборачивать ошибки: внизу, в середине или наверху. Аня нарисовала схему из трёх этажей и сразу оговорилась, что это стратегия, а не закон. Спор закончился общей договорённостью команды.
у каждого уровня программы своя работа с ошибками: нижний — сентинелы, средний — оборачивание контекстом через %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печатает полный стек в исторических библиотеках
Проверьте себя
На верхнем уровне нужно отличить «файл не найден» от «БД недоступна». Что использовать?
Какие роли у уровней программы в стратегии ошибок?
Чем плох strings.Contains(err.Error(), "not found")?
правильных ответов
Нижний уровень — сентинелы; средний — %w-контекст; верхний — Is/As. Схема — стратегия, а не закон: оборачивание в repo допустимо. Ошибка — это интерфейс, по которому общаются уровни, а не строка для печати.
10 000 ₽ · 60 минут · онлайн