язык: объявлена граница правила
- область правила — от его заголовка до следующего заголовка любого уровня; метка открывает блок, хвост после ПОЧЕМУ — продолжение обоснования, а таблица после модальной метки — часть нормы - проверка «заглавных модальных слов вне правил нет» стала реализуемой: прозой считается то, что лежит вне областей правил - нормы, сидевшие в хвостах, подняты в блок нормы: заведены SLOG-25.4 и GERR-26.3, у GTIM-12 «базовый слой» заменён на TIME-12
This commit is contained in:
@@ -344,8 +344,9 @@ HTTP-клиентов, файловой системы, внешних SDK.
|
||||
|
||||
| № | Где перехвачена паника | Что дальше |
|
||||
|---|---|---|
|
||||
| GERR-26.1 | обработчик HTTP-запроса | ответ 500, если он ещё не начат; процесс и прочие запросы не затрагиваются |
|
||||
| GERR-26.1 | обработчик HTTP-запроса, паника любая, кроме сигнала намеренного прерывания | ответ 500, если он ещё не начат; процесс и прочие запросы не затрагиваются |
|
||||
| GERR-26.2 | итерация цикла обработки — бот, воркер | цикл продолжается со следующего элемента, упавший элемент повторно не берётся |
|
||||
| GERR-26.3 | обработчик HTTP-запроса, паника — сигнал намеренного прерывания (`http.ErrAbortHandler`) | значение пробрасывается дальше, ответ не подменяется |
|
||||
|
||||
**ПОЧЕМУ.** Паника внутри обработки одного элемента почти всегда говорит о
|
||||
баге в работе с данными этого элемента, а не о порче общего состояния, —
|
||||
@@ -356,10 +357,11 @@ HTTP-клиентов, файловой системы, внешних SDK.
|
||||
обязательным (GERR-22): неперехваченная паника в любой горутине завершает весь
|
||||
процесс.
|
||||
|
||||
Продолжать, не исключив упавший элемент, нельзя: детерминированная паника
|
||||
даёт бесконечный цикл — тот же элемент, тот же стек, залитый лог и нулевой
|
||||
прогресс. Это классический poison message, и лекарство берём то же, что
|
||||
принято в очередях: элемент выводится из оборота, а не берётся снова. У
|
||||
Исключение упавшего элемента в GERR-26.2 — не осторожность, а условие
|
||||
прогресса: детерминированная паника даёт бесконечный цикл — тот же элемент,
|
||||
тот же стек, залитый лог и нулевой прогресс. Это классический poison message,
|
||||
и лекарство здесь то же, что принято в очередях: элемент выводится из
|
||||
оборота, а не берётся снова. У
|
||||
цикла, который и так подтверждает прогресс — сдвигает офсет, помечает
|
||||
строку состоянием, — механизм для этого уже есть, заводить отдельный не
|
||||
нужно.
|
||||
@@ -369,9 +371,10 @@ HTTP-клиентов, файловой системы, внешних SDK.
|
||||
клиент получит обрывок с кодом 200. Отсюда же общее предпочтение собирать
|
||||
ответ целиком до записи там, где это возможно.
|
||||
|
||||
Из GERR-26.1 есть одно исключение: `http.ErrAbortHandler` — сигнал «прервать
|
||||
обработку намеренно», и recover-обёртка пробрасывает его дальше, а не
|
||||
превращает в 500. Так поступают и стандартные обёртки вроде chi.
|
||||
Отдельная строка GERR-26.3 нужна потому, что `http.ErrAbortHandler` — не
|
||||
отказ, а сигнал «прервать обработку намеренно»: подмена его на 500 превратила
|
||||
бы штатный разрыв в ложную ошибку в логе и в метриках. Так поступают и
|
||||
стандартные обёртки вроде chi.
|
||||
|
||||
### GERR-24. Независимые ошибки собираются `errors.Join`
|
||||
|
||||
|
||||
@@ -337,6 +337,7 @@ ctx = logctx.With(ctx, log) // достаём логгер из ctx в кажд
|
||||
| SLOG-25.1 | штатный конфликт состояния или некорректный ввод | пользователю, он уже получил ответ | `DEBUG` |
|
||||
| SLOG-25.2 | расхождение производного или учётного состояния, первичные данные целы | владельцу, «может стать проблемой» | `WARN` |
|
||||
| SLOG-25.3 | сбой БД, ФС, недоступность зависимости | владельцу, в разбор | `ERROR` |
|
||||
| SLOG-25.4 | класса нет: отказ в классификацию не заведён | владельцу, как пропуск в классификации | `ERROR` с отметкой о непокрытом классе |
|
||||
|
||||
**ПОЧЕМУ.** Это применение SLOG-8 к отказам: пользователь уже увидел причину на
|
||||
экране — владельцу разбирать нечего; целостность первичных данных отделяет
|
||||
@@ -349,9 +350,11 @@ ctx = logctx.With(ctx, log) // достаём логгер из ctx в кажд
|
||||
таблицу не входит: это не доменный отказ, и логирует его recover-граница
|
||||
вместе со стеком (конвенция `errors`). Искать его класс здесь не нужно.
|
||||
|
||||
Мимо таблицы идёт и доменная ошибка, которой нет в маппинге: класса у неё
|
||||
нет, потому что её просто забыли завести. Она логируется `ERROR` с
|
||||
признаком непокрытой (`GERR-25`).
|
||||
Строка SLOG-25.4 говорит не о классе отказа, а о пропуске в самой
|
||||
классификации: ошибку забыли завести в маппинге. `ERROR` здесь — громкость,
|
||||
по которой пропуск находят фильтром, а не оценка тяжести отказа; саму отметку
|
||||
о непокрытом классе ставит трансляция ошибки (`GERR-25` в конвенции
|
||||
`errors`).
|
||||
|
||||
### SLOG-26. Тот же отказ в асинхронной стадии — уровнем выше
|
||||
|
||||
|
||||
@@ -180,8 +180,8 @@ func utcTime(_ []string, a slog.Attr) slog.Attr {
|
||||
текущего значения настройки: смена зоны задним числом сдвигает границы
|
||||
суток у того, что давно посчитано и сохранено.
|
||||
|
||||
Календарные вычисления бизнес-логики берут зону явно — как описано в
|
||||
базовом слое.
|
||||
Явную зону в календарных вычислениях требует TIME-12 — это его правило, а не
|
||||
второе такое же здесь.
|
||||
|
||||
## Связано
|
||||
|
||||
|
||||
Reference in New Issue
Block a user