From f073a68f75f30be92875ba9ef7d392a3a6654b00 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Sat, 25 Jul 2026 20:15:36 +0300 Subject: [PATCH] =?UTF-8?q?web-ui:=20=D1=81=D0=B1=D0=BE=D0=B9=20=D0=B1?= =?UTF-8?q?=D0=B5=D0=B7=20=D1=84=D1=80=D0=B0=D0=B3=D0=BC=D0=B5=D0=BD=D1=82?= =?UTF-8?q?=D0=B0=20=D0=B8=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=20=D0=B1?= =?UTF-8?q?=D0=B5=D0=B7=20=D0=BF=D0=BE=D0=BB=D1=8F=20=D0=BF=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D1=85=D0=BD=D0=BE=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - R34: глобальный слушатель htmx:responseError — на 5xx htmx ничего не свопит, и интерфейс замирает без признака сбоя - R35: 400 вместо поверхности по умолчанию, иначе своп идёт с чужим id - в R14 снято противоречие: слушатель больше не числится среди отвергаемых настроек --- conventions/stack/htmx/web-ui.md | 45 ++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/conventions/stack/htmx/web-ui.md b/conventions/stack/htmx/web-ui.md index 9523d73..b99b858 100644 --- a/conventions/stack/htmx/web-ui.md +++ b/conventions/stack/htmx/web-ui.md @@ -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 приложения;