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 получил настройки с числовым значением
This commit is contained in:
av
2026-08-03 17:14:53 +03:00
parent de7b15d48c
commit d79189be18
94 changed files with 1234 additions and 566 deletions
+24
View File
@@ -0,0 +1,24 @@
# Ошибки
- Только стандартный `errors` + `fmt.Errorf`. Сторонних пакетов ошибок нет:
контекст несёт `slog`, стек-трейсы для домашнего сервиса избыточны.
- Контекст добавляем обёрткой `%w` — это дефолт, чтобы `errors.Is`/`As`
работали сквозь слои. `%v` — только когда причину сознательно не
раскрываем.
- Стиль сообщения: со строчной, без точки, без «failed to». Контекст —
операция или субъект (`"open archive: %w"`), каждый слой добавляет **свой**
смысл, не повторяя нижний.
- Граничные ошибки транслируем в доменные у источника: `sql.ErrNoRows`
`store.ErrNotFound` внутри `store`, чтобы выше не торчал `database/sql`.
- **Sentinel** (`var ErrNotFound = errors.New(...)`) — для условий, на которые
ветвится код. **Типизированная ошибка** — когда вызывающему нужны данные
ошибки. Не плодим типы там, где хватает sentinel.
- Наружу (HTTP) отдаём человекочитаемое сообщение по доменной ошибке, не
сырой `err.Error()`. Маппинг доменная ошибка → статус живёт в одной точке
в `httpapi`; новая штатная ветвь отказа заводится sentinel'ом и
добавляется туда, иначе `default` отдаст 500 на нормальный конфликт.
- Собрать независимые ошибки (валидация конфига — все проблемы разом) —
`errors.Join`.
- `panic` — только невосстановимое: нарушенный инвариант, сбой инициализации.
`recover` — на верхней границе HTTP-обработчика.
- Глушить ошибку без лога — только с однострочным комментарием «почему».