Собралось без ошибок и упало у первого пользователя: четыре падения, которые не ловит проверка модулей

20.09.26

Разработка - Рефакторинг и качество кода

Синтаксический контроль прошёл, валидатор формы прошёл, сборка прошла, автопрогон написал что ошибок нет. Через час четыре падения подряд, все на том, что мы сами не нажимали. Разбираю все четыре, включая самое коварное: загрузчик молча выбрасывает элемент формы из-за одной буквы в теге, и отладка уходит в модуль, где всё правильно.

Обработка собралась. Синтаксический контроль прошёл. Валидатор формы прошёл. Автопрогон отработал и написал "ошибок нет". Отдаём.

Через час прилетает четыре падения подряд. Все четыре на том, что мы сами не нажимали.

Ниже разбор всех четырёх: что упало, почему проверки молчали и что пришлось завести, чтобы такое ловилось до выдачи, а не после. Последний случай самый неприятный: там всё дело в одной букве, и платформа про неё не говорит ни слова.

 

Четыре падения

 

Что упало Сообщение Почему проверки молчали
НачатьЗапускПриложения с Неопределено без текста клиентская ветка вызывается только после сборки файла
чтение КонсольГотова Преобразование значения к типу Булево не может быть выполнено модульная переменная читалась раньше первого присваивания
Параметры = Новый Структура(...) Поле объекта недоступно для записи (Параметры) имя занято свойством управляемой формы, оно только для чтения
Элементы.ПолеТаблицы Поле объекта не обнаружено (ПолеТаблицы) элемент был в Form.xml, но загрузчик выбросил его молча

 

Общее у всех четырёх: синтаксис корректен. Поэтому и молчали проверки. Синтаксический контроль смотрит на текст модуля, а падает выполнение.

 

Случай первый и второй: состояние, которого ещё нет

Два первых падения это один класс, хоть и выглядят по-разному.

Модульная переменная объявлена, но присваивается в обработчике, который к моменту чтения ещё не отработал:

&НаКлиенте
Перем КонсольГотова;

&НаКлиенте
Процедура ОбновитьСостояние()
    Если КонсольГотова Тогда   // здесь Неопределено, а не Ложь
        ...

В 1С необъявленное состояние это Неопределено, а не Ложь. Условие с ним не сравнивает, а падает. Синтаксически всё безупречно: переменная объявлена, тип не указан, потому что его и нельзя указать.

Лечится одной строкой в ПриОткрытии или проверкой через ЗначениеЗаполнено. Но найти это можно только выполнением, причём выполнением именно в том порядке, в котором нажимает пользователь.

То же со вторым: НачатьЗапускПриложения получил Неопределено вместо пути, потому что путь заполняется в другой ветке, которая при этом сценарии не отрабатывала.

Вывод отсюда скучный, но полезный: клиентские ветки, которые вызываются только после какого-то шага, автопрогоном не покрываются, если прогон этот шаг не делает. У нас прогон жал одну команду из трёх.

 

Случай третий: имя, которое уже занято платформой

Это ловушка, на которую наступают все, кто пишет формы руками:

&НаСервере
Процедура ЗаполнитьНастройки()
    Параметры = Новый Структура("Путь, Режим");   // Поле объекта недоступно для записи

У управляемой формы есть собственное свойство Параметры, и оно только для чтения. Своя переменная с таким именем в модуле формы объявиться не может: имя разрешается в свойство формы, и присваивание падает.

Полный список того, во что нельзя писать, платформа нигде не печатает одним местом, но практически это Параметры, Элементы, Команды, Модифицированность, ЭтотОбъект и ещё несколько. Ошибка вылезает только при выполнении конкретной процедуры.

Мы завели на это отдельную проверку: скрипт проходит по модулю формы и ищет присваивание в любое имя из закрытого списка. Проверка тупая, ловит за секунду, а стоила бы иначе одного падения у покупателя.

 

Случай четвёртый: одна буква, и элемента в форме нет

Вот это стоит запомнить всем, кто собирает формы из XML, генерирует их скриптами или правит выгрузку руками.

В Form.xml был элемент с тегом:

<SpreadsheetDocumentField name="ПолеТаблицы">

Правильно пишется SpreadSheetDocumentField, с заглавной S в середине. Разница в одной букве.

Что делает загрузчик конфигурации: выбрасывает такой элемент молча. Не ошибка, не предупреждение, не строка в лог. Сборка проходит успешно, файл получается, форма открывается. Элемента в ней просто нет, и первое же обращение Элементы.ПолеТаблицы падает с "Поле объекта не обнаружено".

При этом человек смотрит на Form.xml, видит там свой элемент и делает единственно возможный вывод: сломан модуль. Полчаса уходит на отладку кода, в котором всё правильно.

Это не единичная особенность одного тега. Ровно так же у нас пропадал VerticalStretch, написанный с другим регистром. Механика общая: неизвестный тег в форме не является ошибкой загрузки, он просто игнорируется.

Как проверять: после сборки сверять состав Form.xml с тем, что фактически оказалось в форме, и отдельно проверять теги по белому списку платформы. У нас это второй скрипт, и он ловит оба симптома: и пропавший элемент, и тег, которого не существует.

Дешёвый вариант без скриптов: собрать, открыть форму в конфигураторе и посмотреть глазами, все ли элементы на месте. Работает, пока элементов десяток.

Как воспроизвести это за пять минут

Если не верите, что платформа молчит, проверьте на любой тестовой обработке:

  1. Выгрузите обработку в XML.
  2. Найдите в Form.xml любой элемент и поменяйте регистр одной буквы в имени тега: например, CheckBoxField на CheckboxField.
  3. Загрузите обратно и соберите.
  4. Откройте форму.

Сборка пройдёт без единого сообщения. Элемента в форме не будет. В Form.xml, который лежит у вас на диске, он при этом на месте, и глазами вы его видите.

Отсюда практический признак для диагностики: если модуль падает на "Поле объекта не обнаружено", а элемент в XML есть, смотрите не на модуль, а на написание тега. Причём именно на регистр: платформа различает SpreadSheetDocumentField и SpreadsheetDocumentField как разные теги, из которых второй ей неизвестен.

Отличить "элемент выброшен" от "элемент не создан" помогает простая проверка прямо из модуля:

&НаСервере
Процедура ПроверитьСоставФормы()
    Для Каждого Элемент Из Элементы Цикл
        Сообщить(Элемент.Имя + " / " + ТипЗнч(Элемент));
    КонецЦикла;
КонецПроцедуры

Список того, что реально загрузилось, сверяется с тем, что вы писали в XML. Расхождение и есть ответ.

Что должен жать автопрогон

После этой истории у нас прогон устроен так, и это минимум, который окупается:

  • каждая команда каждой формы, а не главный сценарий. Команда, которая открывает другую форму, тоже жмётся, и в открывшейся форме жмутся её команды;
  • результат пишется после каждого нажатия, а не общим итогом. Общий итог "ошибок нет" ровно так и скрыл, что до третьей кнопки прогон не доходил: он падал молча и заканчивался успехом;
  • проверяется не отсутствие исключения, а результат: таблица заполнилась, файл создался, поле не пустое. Команда, которая тихо ничего не сделала, для прогона это успех, а для пользователя нет;
  • прогон запускается на пустой базе тоже. Половина падений на состоянии вылезает именно там, где нет данных и переменные остаются незаполненными.

Последний пункт добавился позже и по такому же поводу: метрика, которая на нагруженном стенде считалась прекрасно, на пустом кластере пропадала целиком, и панель у покупателя оказывалась пустой в первый час знакомства с продуктом.

 

Почему все проверки были зелёными

Стоит разобрать отдельно, потому что это общий случай, а не частность про формы.

У нас было три уровня проверки, и каждый честно делал свою работу:

  • синтаксический контроль смотрит текст модуля. Все четыре падения синтаксически корректны, ему не за что зацепиться;
  • валидатор формы проверяет структуру XML: обязательные атрибуты, корректность вложенности. Тег с опечаткой структуру не нарушает, он просто лишний;
  • автопрогон запускает обработку и жмёт кнопку. Одну. Из трёх.

Каждый уровень отвечал "у меня чисто", и вместе они складывались в ощущение покрытия, которого не было. Это и есть самое дорогое в истории: не четыре падения, а ложная уверенность перед выдачей.

Сравните с тем, как выглядит правда: покрытие было одна команда из трёх, то есть 33 %, а отчёт печатал "ошибок нет" и выглядел как 100 %.

Отдельно стоит сказать про соблазн, который возникает после такой истории: добавить ещё один уровень проверки и успокоиться. Он не помогает, если новый уровень смотрит туда же, куда смотрели прежние. Четвёртое падение не поймал бы ни один анализатор кода, каким бы умным он ни был: в коде всё правильно, ошибка живёт в XML формы и проявляется только тем, что элемент не доехал. Проверка должна была сравнить два состояния между собой, а не проверить каждое по отдельности, и в этом вся разница.

Тот же принцип работает и в обратную сторону. Когда среда падает без внятного текста, первым делом стоит прогнать через неё заведомо исправный артефакт: чужую рабочую обработку, простейший запрос, пустую форму. Одна минута, а разделяет "сломан мой код" и "сломана среда". У меня был случай, когда HTTP-сервис отдавал страницу 500 вместо JSON на любой вызов, и полчаса это выглядело как дефект модуля, пока тот же вызов не упал точно так же на заведомо рабочем файле. Дело оказалось в правах пользователя сервиса, а не в коде.

 

Что мы поменяли

Три вещи, все дешёвые:

  1. Автопрогон жмёт каждую команду каждой формы, включая те, что открывают другие формы, и пишет результат после каждой, а не общий итог в конце. Общий итог скрывал, что до третьей кнопки прогон не доходил.
  2. Проверка присваиваний в свойства формы по закрытому списку имён.
  3. Сверка Form.xml с фактическим составом формы плюс проверка тегов по белому списку.

Оба скрипта проверены воспроизведением: специально ломали регистр буквы в теге и специально писали в Параметры, оба симптома ловятся.

И четвёртое, не техническое. Перед тем как писать форму, стоит посмотреть, делали ли мы такую раньше. Форма справки у нас к тому моменту была написана пять раз, и во всех пяти это одно поле HTML-документа с модулем в шесть строк. Здесь я написал своё устройство с двумя полями и сторожем готовности, и именно оно принесло второе падение. Копирование работающего скучнее, но дешевле.

 

Правило, которое я вынес

Кнопка, которую не нажал автопрогон, это кнопка, которую нажмёт пользователь.

Формулировка звучит очевидно, пока не посмотришь на свой прогон и не посчитаешь, сколько команд он реально трогает. У нас было три команды и одна нажималась.

Второе следствие шире: отсутствие ошибки не равно успеху. Загрузчик, который молча выбрасывает неизвестный тег, сообщает об успехе. Прогон, который дошёл до первой кнопки, сообщает об успехе. Признаком успеха стоит считать полезный результат (элемент есть в форме, команда отработала и вернула данные), а не молчание инструмента.

 

Вопрос

Мне интересно, как с этим у тех, кто собирает формы генераторами. Судя по тому, что теги выбрасываются без предупреждения, наступать на это должны регулярно, но в обсуждениях я такого почти не встречал: обычно пишут про ошибки загрузки, а не про молчаливое исчезновение.

Если у вас есть способ заставить платформу ругаться на неизвестные теги формы при загрузке, напишите, пожалуйста. Я такого ключа не нашёл, и проверку пришлось делать снаружи, своим скриптом. Возможно, зря.

Другие наши инструменты для разработчика 1С:

Вступайте в нашу телеграмм-группу Инфостарт

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Рефакторинг и качество кода Тестирование QA Разработчик Бесплатно (free)

Штатная страховка внутри цепочки обработки умеет прятать дефекты того шага, который стоит перед ней. У нас так и вышло: валидатор чинил результат постфактум, на выходе всё выглядело корректно, и никто не видел, что предыдущий шаг молча теряет данные. Вылезло это только на независимой проверке чужими глазами. Разбираю, чем инвариант отличается от сценарного теста и почему обычное умножение вытащило дефект из красивой метрики 0,997. Отдельно про 13 дублей, которые приехали из источника ещё до всякой обработки, и про две находки, которые оказались вообще не моими: они жили в эталонной реализации, откуда я списывал логику. Вторая часть про лимит выхода модели: почему обрезка ответа по длине это тихий ноль в мониторинге и как смена формата на дельты уронила выход до 4 951 токена. Есть отклонённые гипотезы и честный список того, чего мы так и не померили.

вчера в 12:20    143    nedomolkov.ivan    1    

1

WEB-интеграция Рефакторинг и качество кода Системный администратор Разработчик 1С 8.3 Бесплатно (free)

Я сел проверять внутренний поисковый сервис по коду: можно ли доверять ему в автоматическом режиме. Сверка с обычным текстовым поиском по файлам дала 261 из 261, 264 из 264 и 182 из 182 совпадений, разбор структуры файла - 318 функций из 318. Стопроцентная точность. Этот же замер и вскрыл, что опираться на сервис нельзя: искал он безупречно, только совсем не в том месте, которое я ему называл. Внутри разбор трёх дефектов, сложившихся в один тихий отказ: аргумент, проглоченный без ошибки; умолчание, выставленное когда-то наугад; снимок данных, у которого в ответе не указан возраст. Плюс регулярное задание, которое вся команда считала работающим и которого не существовало никогда. Перенос на 1С прилагается: готовый цикл проверки, после которого HTTP-сервис перестаёт молча принимать мусор.

вчера в 12:10    149    nedomolkov.ivan    0    

0

Логистика, склад и ТМЦ Рефакторинг и качество кода Разработчик Аналитик Руководитель проекта 1С 8.3 Бесплатно (free)

Кладовщик получает задачу: на складе проверки лежат две штуки. Идёт в зону, а там всё на месте и никакой задачи в складской системе нет. Так работала автоматическая сверка остатков между учётной и складской системами: разницу она переносила документом, а комментарий к этому документу восемь месяцев отправлял людей искать несуществующий ноль. Робота разобрали до кода. Обе сравниваемые величины оказались синтетическими: слева физический срез с вычетами по активности и окнами в 60 минут и 12 часов, справа учётный остаток на конец дня минус трёхчасовой хвост непроведённых ордеров. Порог срабатывания стоял в нуле, поэтому робот исправно оформлял собственный шум измерения: за 60 дней он сам создал 62,7% оборота технического склада, а 2 081 артикул из 2 102 приезжал туда и уезжал обратно. Внутри обе формулы, замер лага отгрузки, снятая гипотеза и честная граница данных.

вчера в 12:00    122    nedomolkov.ivan    0    

0

Рефакторинг и качество кода Нейросети Разработчик 1С 8.3 Бесплатно (free)

Как за вечер проверить, годится ли локальная модель для поиска ошибок в вашем коде 1С, и не обмануть себя по дороге. Разбираю замер Qwen2.5-Coder 1.5B, 3B и 7B на коде с заранее известными дефектами: почему полноту и шум надо считать раздельно, как 3B набирает высокий балл, вообще не читая код, сколько минут уходит на боевую процедуру на процессоре и на GTX 1650, и чем кончилась попытка подложить модели справку по методам платформы.

16.09.2026    1099    nedomolkov.ivan    4    

1

Инструментарий разработчика Нейросети Рефакторинг и качество кода Аналитик Пользователь Руководитель проекта Бесплатно (free)

Железо перестало быть проблемой, и качество ответов немедленно встало в потолок. Дальше пошли три улучшения, каждое из которых выглядело очевидно правильным: свой справочник стандартов, код процедур в поисковом индексе и переписывание вопроса отдельной моделью. Первое работало, но стоило пятнадцать тысяч токенов в каждом запросе. Второе уронило находимость на двадцать процентов. Третье уронило качество с 0,864 до 0,782 и растянуло прогон с 88 секунд до 302. Рассказываю, чем я это померил, почему на глаз ни одно ухудшение не видно и почему добавление правдивой информации регулярно делает поиск хуже.

14.09.2026    648    solbol    0    

3

Рефакторинг и качество кода Нейросети Разработчик 1С:Предприятие 8 Бесплатно (free)

Продолжение статьи «BSL Language Server внутри 1С:EDT: коннектор, которого не хватало». Там мы научили EDT видеть расширенную диагностику BSLLS, а здесь замкнем контур: научим ИИ-агентов автоматически исправлять эти ошибки строго по официальным стандартам разработки 1С.

02.09.2026    1779    malikov_pro    2    

6

Нейросети Рефакторинг и качество кода Разработчик 1С 8.3 Бесплатно (free)

В справочнике дополнительных обработок любой базы старше трёх лет лежит два-три десятка файлов. Часть писали вы, часть предыдущий разработчик, часть прислал подрядчик. Завтра одну из них надо править, и первый вопрос не "как править", а "что она вообще делает". Обычный ответ - открыть и читать: полторы тысячи строк это полдня. Показываю, как уложиться в пять минут: пять шагов, у каждого сказано, что он даёт. Внутри распределение 1 135 находок по ста чужим обработкам (четыре первых места из шести - одно и то же), что нашлось в наших собственных обработках, и честный список того, чего этот способ не даёт.

01.09.2026    1956    nedomolkov.ivan    6    

2
Для отправки сообщения требуется регистрация/авторизация