Files
av d79189be18 docs: документация переведена на канон av-dev-pm
- беклог и план переехали в docs/tasks (38 задач, 11 целей), слаги
  переименованы с транслита на английские, 85 ссылок поправлены
- conventions.md разобран в docs/conventions/, local-research.md — в
  docs/research/, review-journal.md — в docs/review.md с разделом настройки
  конвейера; заведены security.md, adr/ и .pm.json
- шаг docs.py check добавлен в task gate; поведение в architecture.md помечено
  девятью маркерами долга, database.md получил настройки с числовым значением
2026-08-03 17:14:53 +03:00

2.3 KiB

Ошибки

  • Только стандартный errors + fmt.Errorf. Сторонних пакетов ошибок нет: контекст несёт slog, стек-трейсы для домашнего сервиса избыточны.
  • Контекст добавляем обёрткой %w — это дефолт, чтобы errors.Is/As работали сквозь слои. %v — только когда причину сознательно не раскрываем.
  • Стиль сообщения: со строчной, без точки, без «failed to». Контекст — операция или субъект ("open archive: %w"), каждый слой добавляет свой смысл, не повторяя нижний.
  • Граничные ошибки транслируем в доменные у источника: sql.ErrNoRowsstore.ErrNotFound внутри store, чтобы выше не торчал database/sql.
  • Sentinel (var ErrNotFound = errors.New(...)) — для условий, на которые ветвится код. Типизированная ошибка — когда вызывающему нужны данные ошибки. Не плодим типы там, где хватает sentinel.
  • Наружу (HTTP) отдаём человекочитаемое сообщение по доменной ошибке, не сырой err.Error(). Маппинг доменная ошибка → статус живёт в одной точке в httpapi; новая штатная ветвь отказа заводится sentinel'ом и добавляется туда, иначе default отдаст 500 на нормальный конфликт.
  • Собрать независимые ошибки (валидация конфига — все проблемы разом) — errors.Join.
  • panic — только невосстановимое: нарушенный инвариант, сбой инициализации. recover — на верхней границе HTTP-обработчика.
  • Глушить ошибку без лога — только с однострочным комментарием «почему».