Смарт-действия — Известные проблемы¶
Документ — реестр известных проблем и ограничений смарт-действий (Smart Actions) 1Формы: активные ограничения (локализация ФИО в CreateUser/UpdateUser, EventID 64 в WhenOpenTask, Lua-ориентированная справка редактора при любом языке скрипта) и ранее исправленные проблемы. Для инженеров поддержки и разработчиков, работающих с пакетами смарт-действий.
1. CreateUser / UpdateUser не поддерживают локализованные ФИО¶
Статус: исправлено
Симптом: при создании пользователя через смарт-действие «Создать пользователя» нельзя указать ФИО на дополнительном языке (например, английском). ФИО записывается как локализация только для языка, указанного в параметре «Язык».
Причина: действие записывает локализованное ФИО только для основного языка пользователя; параметров для второго языка нет.
Решение: в действиях «Создать пользователя» и «Обновить пользователя» добавлены параметры «Фамилия (локализованная)», «Имя (локализованное)», «Отчество (локализованное)» и «Язык локализации» — ФИО на дополнительном языке задаётся штатно. См. actions-reference-people.md. Ограничение касается только одного действия: при обычном сохранении карточки пользователя локализованные ФИО распространяются на языки-автокопии — см. Локализация — бизнес-правила.
2. WhenOpenTask (EventID 64) срабатывает в SPA только в представлении «Чаты»¶
Статус: ограничение подтверждено, поведение намеренное
Симптом: смарт-правило на событие «Во время открытия задачи» не срабатывает, когда пользователь открывает задачу в стандартной карточке (полное представление). Срабатывает только при открытии в представлении «Чаты».
Обходной путь: событие можно вызвать напрямую через API (POST /api/v2/tasks/{taskId}/when-open-task) — без ограничений по представлению. Актуально для интеграций и мобильного клиента.
Дополнительно: контекст открытия передаётся в @eventParam1 (не @eventParam0). @eventParam0 у данного события не используется — нетипичное поведение по сравнению с другими событиями.
3–6. Исправленные ранее проблемы (сборки 2.268.63 – 2.268 «Скульптор»)¶
Четыре исправленные ранее проблемы с указанием сборок исправления; в текущих сборках не воспроизводятся.
Mustache-шаблоны возвращали пустые строки (исправлено в 2.268.77): смарт-действие «Сгенерировать файл по шаблону» с mustache-шаблоном возвращало пустое содержимое.
Смарт-отмена (Cancel) в Lua не работала (исправлено в 2.268.63): действие «Отменить» (Cancel) не отрабатывало корректно при вызове из Lua-скрипта.
Ошибка 500 на смарт-кнопках действий (исправлено в 2.268.74): ошибка при нажатии на смарт-кнопки действий (в частности, при генерации файла по шаблону).
HTML-таблица с числовыми отступами обрывала формирование файла по шаблону (исправлено в 2.268 «Скульптор»): значение с <table cellspacing="0"> или <table cellpadding="0"> приводило к ошибке The input string '"0"' was not in a correct format и отказу действия «Сгенерировать по шаблону». Теперь такие значения формируются так же, как записанные с обычными кавычками.
6. ESQL: FROM {0} без алиаса — 500 на reserved keyword¶
Статус: исправлено
Симптом: запросы вида SELECT VALUE COUNT(1) FROM {0} WHERE ... возвращают 500. Проявлялось при вычислении видимости блоков смарт-фильтра в МТФ.
Причина: в бесконтекстной ветке генератора ESQL конструкция FROM {0} подставлялась без алиаса коллекции. Парсер ESQL принимал стоящий сразу за FROM reserved keyword (WHERE, ORDER, GROUP) за имя коллекции. В контекстной ветке (FROM Tasks as t) алиас присутствовал, поэтому ошибка не воспроизводилась.
Инвариант: алиас as t подставляется во всех ветках генератора ESQL.
7. Потеря значения параметра действия через admin-MCP (JsonElement)¶
Статус: исправлено
Симптом: при сохранении действия пакета через admin-MCP (/mcp-admin-api-actions-pack-editor → actions_pack_editor_save_pack_action) значение параметра не записывалось в БД. Проявлялось двумя способами:
- ArgumentException: unknown value type: System.Text.Json.JsonElement — значение не распознавалось контролом параметра.
- SqlException 547 — нарушение CHECK-ограничения CK_PacksActionsParameters_Value_XOR_Expression при вставке параметра с пустым значением.
Причина: admin-MCP десериализует тело запроса через System.Text.Json, помещая в object-поле FixedValue тип JsonElement. Базовый класс контролов ParameterControlBase обрабатывал только JObject (Newtonsoft) и нативные типы — JsonElement попадал в else-ветку с исключением. Отдельно — отсутствие фильтрации пустых параметров в MergeParameters позволяло довести до БД строку с пустыми значениями всех источников.
Инвариант: ParameterControlBase.SerializeValue обрабатывает JsonElement наравне с JObject; PacksActionsEntityService.MergeParameters фильтрует параметры без значения через HasParameterValue перед записью.
8. CreateUser / UpdateUser: поле «Пароль» в редакторе всегда пустое, отдельной очистки нет¶
Симптом: в редакторе пакета действий поле «Пароль» действий «Создать пользователя» и «Изменить пользователя» всегда отображается пустым, даже если пароль был задан ранее. Отдельного способа очистить ранее сохранённый пароль в интерфейсе нет.
Причина: значение пароля хранится в зашифрованном виде и намеренно не возвращается в редактор, в описание действия и в экспорт модуля — поле работает только на запись. Пустое поле при сохранении трактуется как «не менять сохранённое значение».
Обходной путь: чтобы заменить пароль, введите новое значение. Чтобы убрать ранее сохранённый пароль, смените источник значения параметра (выражение, скрипт или предопределённый параметр) либо пересоздайте действие.
9. Невалидный JSON в значении параметра действия пакета — 500 вместо ошибки ввода¶
Статус: исправлено
Симптом: сохранение действия пакета со значением параметра, структура которого не соответствует контролу — например, у элемента выбора пользователей идентификатор пустой, — отвечало HTTP 500, а в журнал исключений писалась ошибка десериализации Error converting value {null} to type 'System.Int32'. Path 'users[0].id'.
Причина: в ParameterControlBase.TryParseNaive десериализация входного значения — JsonElement.Deserialize<TV> для запросов от admin-MCP и JObject.ToObject<TV>() для запросов от SPA — выполнялась без перехвата: исключение уходило наверх мимо фильтра, который переводит логические ошибки в 400.
Решение: блок десериализации обёрнут в try/catch, перехватывающий System.Text.Json.JsonException, Newtonsoft.Json.JsonException, InvalidCastException и ArgumentException, и вместо них бросается TCLogicException с сообщением «некорректное значение параметра действия» — фильтр API транслирует её в HTTP 400. Поведение наследуют все контролы на базе ParameterControlBase<TV>; разбор корректных значений не изменился.
10. Справка в редакторе смарт-скриптов всегда Lua-ориентированная¶
Симптом: в скрипте на языке, отличном от Lua (Python, JavaScript, OneScript, C#), кнопка «i» («Библиотека подсказок») открывает окно с заголовком «Помощь по lua-скриптам» и содержимым про Lua: RESULT, CONTEXT как объект задачи/пользователя/письма, var_dump, is_empty, вкладка «Смарт-действия». В Python и остальных языках эти имена и конструкции не работают.
Причина: справка — единый текст из ресурсов интерфейса (ключи luaDoc.* словаря common). Язык скрипта в компонент справки не передаётся, переключение её содержания по языку не реализовано; кнопка выводится в тулбаре независимо от языка, а заголовок берётся из ресурса common.helpWithLuaScripts.
Обходной путь: штатного переключателя справки нет. Для Python ориентир — python-scripting.md: ключи ctx, возврат результата, ограничения песочницы; для остальных языков — документы домена по соответствующему языку.
11. Правило «После смены ДП» из другого правила читало значение параметра до изменения¶
Статус: исправлено
Симптом: правило на событие «После смены ДП», запущенное смарт-действием другого правила, в смарт-выражении получало прежнее значение изменённого параметра — и при чтении из денормализованной таблицы категории, и из значений параметров. Тот же результат давало сохранение пачки параметров одной операцией.
Причина: смарт-выражение выполнялось под отдельной строкой подключения, в собственной сессии базы, и не видело записи, сделанной смарт-действием внутри текущей операции: запись оставалась незафиксированной до её конца.
Решение: признак «читать основной строкой подключения внутри текущей транзакции» удерживается на самой транзакции — при сохранении значения параметра и при сохранении пачки транзакция помечается, и смарт-выражение внутри неё читает записанное значение. Вне таких операций поведение не изменилось. Вошло в сборку 2.268 «Скульптор».
12. «Время ожидания выполнения истекло» по смарт-выражению при сохранении факта¶
Статус: исправлено в 2.268 «Скульптор»
Симптом: при сохранении трудозатрат с каскадом на проект в журнале ошибок появляются записи о таймауте смарт-выражения, а значение параметра проекта считается по старым данным; пользователь повторяет сохранение.
Причина: выражение в режиме XML-формулы при заданной отдельной строке подключения для смарт-выражений считалось вне транзакции запроса и в другой сессии базы. При уровне изоляции соединения из пула выше «повторяемого чтения» оно ожидало блокировку, которую держала транзакция самого запроса, — отсюда таймаут; при более слабом уровне виден был устаревший результат.
Исправлено. На MS SQL выражение в режиме XML-формулы считается в транзакции вызвавшего запроса и в его сессии, поэтому видит записанное в этой же транзакции. Выражения с собственным T-SQL под отдельной строкой подключения и поведение на PostgreSQL не менялись.
Обходной путь (на сборках до исправления): нет; записи о таймауте по сохранению факта на исправленной сборке не воспроизводятся. Если симптом остался — проверить, что у выражения нет собственного T-SQL, и уточнить сборку площадки.
13. Подсказка типа результата действия «Распаковать» расходилась с рантайм-типом при пропущенных записях¶
Статус: исправлено (сборка 2.268 «Скульптор»)
Симптом: в редакторе смарт-скриптов у действия «Распаковать» подсказка результата показывала int[]; если в архиве были повреждённые записи или записи, пропущенные по лимитам, скрипт получал объект с полями fileIds и skippedEntries, и штатные приёмы работы с массивом (#, ipairs, table.insert) на нём не работали. Смарт-выражение последующего действия, ссылавшееся на результат разархивации, падало с ошибкой Entity SQL.
Причина: действие объявляет ResultType = int[], а при пропущенных записях возвращает UnzipArchiveResult; в параметр смарт-выражения значение попадало без приведения к массиву.
Исправлено. Подсказка в редакторе показывает обе формы — int[] | { fileIds (int[], 1..n), skippedEntries (string[], 1..n) }, значение UnzipArchiveResult на границе Lua отдаётся таблицей, а в параметр смарт-выражения передаётся массив идентификаторов распакованных файлов. Подробности о форме результата — в справочнике действий, раздел «Файлы (расширение)».
Обходной путь: нет. Признак старого поведения — подсказка результата у действия «Распаковать» показывает только int[], а при пропущенных записях скрипт получает объект.
Связанные документы:
- Файлы — справочник действий, раздел «Файлы (расширение)»
14. «Экспортировать данные в Excel»: выгрузка падает на вычисляемых текстовых колонках¶
Статус: в работе
Симптом: действие отказывает с текстом Column '<имя колонки>' is read only, файл не создаётся. На PostgreSQL так ведёт себя любая функция с текстовой колонкой; на MS SQL — процедура, у которой строковая колонка получена выражением: склейкой строк, CASE, ISNULL, литералом, параметром процедуры или CAST/CONVERT.
Причина: после перевода вызова на общий доступ к базе результат читается в таблицу данных, и драйвер помечает колонки-выражения как нередактируемые. Генератор файла переписывает текстовые ячейки (срезает HTML-разметку, обрезает краевые пробелы), а запись в такую колонку запрещена. До перевода результат читался способом, который этот признак не выставлял, и те же процедуры выгружались.
Обходной путь: выбирать в процедуре колонки из таблиц и табличных переменных — они остаются редактируемыми. Текст, собираемый выражением, формировать на стороне пакета либо отдельными действиями.
Когда обращаться в поддержку 1Ф: если процедура отдаёт только колонки из таблиц и отказ всё равно воспроизводится — приложить версию площадки, текст ошибки из журнала ошибок платформы и текст процедуры.
15. «Экспортировать данные в Excel»: ошибка после второго набора не останавливает действие¶
Статус: в работе
Симптом: процедура на MS SQL вернула два и более набора и упала после второго (RAISERROR уровня 11 и выше, THROW, ошибка выполнения) — действие завершается успешно, в задачу вкладывается файл с данными первого набора, в журнале ошибок записи нет, пакет идёт дальше. При откате транзакции внутри процедуры изменения откатываются, а файл с данными отменённого расчёта остаётся в задаче.
Причина: чтение останавливается на первом наборе с колонками; остаток ответа дочитывается при закрытии соединения, а ошибка этой части при закрытии не поднимается. На PostgreSQL проблема не проявляется: функция, завершившаяся ошибкой, строк не отдаёт и вызов падает целиком.
Обходной путь: не держать в одной процедуре с выгрузкой инструкции, способные упасть после выборки, — вынести их отдельным действием пакета либо перестроить процедуру так, чтобы она падала до возврата данных.
Когда обращаться в поддержку 1Ф: при подозрении на частичные данные в приложенном файле — приложить версию площадки и текст процедуры: по журналу пакета такой отказ не виден.