web-ui: сбой без фрагмента и запрос без поля поверхности
- R34: глобальный слушатель htmx:responseError — на 5xx htmx ничего не свопит, и интерфейс замирает без признака сбоя - R35: 400 вместо поверхности по умолчанию, иначе своп идёт с чужим id - в R14 снято противоречие: слушатель больше не числится среди отвергаемых настроек
This commit is contained in:
@@ -203,16 +203,35 @@ s.render(w, "source_block", view) // фрагмент = тот же шаб
|
||||
сообщением; доменная ошибка на htmx-пути не транслируется в HTTP-статус.
|
||||
|
||||
**Почему.** В htmx 2.x ответы 4xx/5xx по умолчанию не свопят DOM — то есть
|
||||
пользователь не увидит ничего. Настроить это можно
|
||||
(`htmx.config.responseHandling`, расширение `response-targets`, слушатель
|
||||
`htmx:responseError`), но любая настройка — свой JS-конфиг на клиенте, и
|
||||
платится она из R1 и R2. Для REST API и не-JS редиректа с `?err=` статус
|
||||
по-прежнему используется: там его кто-то читает.
|
||||
пользователь не увидит ничего. Своп ошибочных ответов настраивается
|
||||
(`htmx.config.responseHandling`, расширение `response-targets`), но любая
|
||||
такая настройка — свой JS-конфиг на клиенте, и платится она из R1 и R2.
|
||||
Сообщить о сбое, для которого фрагмента нет вовсе, — отдельная задача, и
|
||||
её решает глобальный слушатель (R34). Для REST API и не-JS редиректа с
|
||||
`?err=` статус по-прежнему используется: там его кто-то читает.
|
||||
|
||||
Цена решения: в логе доступа провалившееся действие выглядит как `200`.
|
||||
Искать его надо по доменной записи об исходе операции (`lang/go/logging.md`),
|
||||
а не по коду ответа.
|
||||
|
||||
### R34. Сбой без ответа-фрагмента показывается глобальным слушателем
|
||||
|
||||
**ДОЛЖЕН.** Один глобальный слушатель `htmx:responseError` и
|
||||
`htmx:sendError` показывает нейтральное сообщение о неудаче запроса; своп
|
||||
ошибочных ответов в целевые регионы (`htmx.config.responseHandling`,
|
||||
`response-targets`) не настраивается.
|
||||
|
||||
**Почему.** R14 закрывает доменный отказ, до которого обработчик дошёл.
|
||||
Паника, сбой шаблона и обрыв сети отдают 5xx или ничего, htmx 2.x такое не
|
||||
свопит — регион не меняется, интерфейс замирает без единого признака сбоя,
|
||||
и пользователь повторяет действие, которое могло уже примениться. Слушатель
|
||||
— несколько строк без доменного состояния, то есть внутри границы R2, и он
|
||||
не спорит с R14: там настройки отвергнуты как замена фрагменту, который
|
||||
обработчик в состоянии отдать, а здесь фрагмента нет по определению. Своп
|
||||
тела ошибки в целевой регион стоил бы дороже: страница 500 не несёт
|
||||
целевого `id`, и после первого же такого свопа регион перестаёт находиться
|
||||
(R5).
|
||||
|
||||
### R15. Наружу идёт сообщение публичного канала
|
||||
|
||||
**ДОЛЖЕН.** Во фрагмент попадает нейтральный текст по правилам
|
||||
@@ -394,6 +413,22 @@ htmx-атрибутов при этом само работает маркеро
|
||||
действием, поэтому связь «эта страница → этот фрагмент» читается там, где
|
||||
её заводят.
|
||||
|
||||
### R35. Запрос без поля поверхности получает 400
|
||||
|
||||
**ДОЛЖЕН.** Обработчик, различающий поверхности (R28), отвечает статусом
|
||||
400, когда поля `surface` в запросе нет; поверхность по умолчанию не
|
||||
выбирается.
|
||||
|
||||
**Почему.** Поле кладёт в форму наш же шаблон, поэтому его отсутствие —
|
||||
дефект формы, а не вход пользователя. Поверхность по умолчанию маскирует
|
||||
такой дефект молча неверным фрагментом: своп с чужим `id` проходит, после
|
||||
чего регион перестаёт находиться таргетом (R5), и ошибка воспроизводится
|
||||
как «интерфейс иногда застывает». 400 не свопится и всплывает сообщением
|
||||
глобального слушателя (R34) — сразу и на той странице, где форму сломали.
|
||||
Вкладка, открытая до появления поля, получает тот же 400 и чинится
|
||||
перезагрузкой; это дешевле, чем молча неверный фрагмент в актуальной
|
||||
разметке.
|
||||
|
||||
## Статика, вендоринг, кэш
|
||||
|
||||
Раздел не про htmx — это упаковка любого server-rendered приложения;
|
||||
|
||||
Reference in New Issue
Block a user