Перейти к содержанию

Смарт-пакеты: типичные ошибки и как их избежать

Документ собирает повторяющиеся ошибки настройки пакетов действий: порядок действий, контекст выполнения (переход vs расписание), привязка к расписаниям, тихие сбои, асинхронные пакеты, отладка и чеклист. Каждая ошибка описана по схеме Симптом — Причина — Решение. Для администраторов платформы, настраивающих смарт-пакеты. Связанные документы: Смарт-действия — администрирование, Справочник смарт-действий, Решение проблем.


1. Порядок действий в пакете — критически важен

Действия в пакете выполняются последовательно, в порядке ActionOrder (таблица PacksActions). Если действие N убирает условие, необходимое для действия N+1, пакет прерывается или даёт неожиданный результат.

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

1.1 «Удалить исполнителей» до перехода

Симптом: выполняются смарт-действия на переходе, но сам переход не происходит. Задача остаётся в прежнем статусе. Лог автоматизации показывает успешное выполнение действий, но перехода нет.

Причина: в пакете действие «Удалить исполнителей» стоит перед действием «Выполнить переход» (MakeStep). Маршрут требует наличия исполнителя для выполнения перехода. После удаления исполнителей переход невозможен — система отклоняет его молча или с ошибкой, которая не всегда видна в интерфейсе.

Решение:

  1. Переместить «Удалить исполнителей» после «Выполнить переход».
  2. Если бизнес-логика требует удаления до перехода — использовать два пакета на двух событиях: пакет «Перед переходом» (удаление) и пакет «После перехода» (назначение новых). Но помнить: действие «Удалить исполнителей» в пакете «Перед переходом» может заблокировать сам переход.
  3. Альтернатива: заменить «Удалить исполнителей» + «Выполнить переход» на «Выполнить переход» + «Удалить исполнителей» + «Добавить исполнителя» (нового). Порядок: переход — удаление старых — назначение новых.

Правило: действия, удаляющие обязательные атрибуты задачи (исполнители, заказчик, обязательные ДП), всегда ставятся после действий, которые эти атрибуты проверяют.

1.2 «Создать задачу» без обязательных ДП

Симптом: действие «Создать задачу» (CreateTask) в пакете завершается с ошибкой или молча не создаёт задачу. В логе автоматизации — запись без результата.

Причина: в целевой категории настроены обязательные ДП или обязательные поля (исполнитель, срок). Действие CreateTask не заполняет их — и создание блокируется валидацией.

Решение:

  1. Проверить обязательные ДП и поля целевой категории.
  2. Добавить в пакет действия «Изменить значение ДП» после CreateTask для заполнения обязательных полей. Учесть: CreateTask возвращает ID созданной задачи (переменная), его можно использовать в последующих действиях через пункт «Переменные» в дереве сущностей.
  3. Если обязательные ДП нужно заполнить при создании — использовать смарт-скрипт (JS/Lua) вместо стандартного действия CreateTask.

1.3 «Изменить ДП» после «Заблокировать ДП»

Симптом: значение ДП не меняется, хотя в логе автоматизации действие «Изменить значение ДП» отмечено как выполненное.

Причина: ранее в том же пакете стоит действие «Заблокировать ДП» (SetExtParamReadOnly) для того же ДП. Блокировка применяется мгновенно, и последующее изменение игнорируется.

Решение:

  1. Поменять порядок: сначала «Изменить значение ДП», затем «Заблокировать ДП».
  2. Если нужно разблокировать, изменить, заблокировать обратно — три действия в правильном порядке: разблокировать — изменить — заблокировать.

Несколько действий меняют один ДП:

Симптом: ДП содержит значение из первого действия, хотя ожидалось значение из второго.

Причина: два действия «Изменить значение ДП» для одного ExtParamID. Оба выполняются, но итоговое значение — из последнего. Если между ними стоит действие, зависящее от промежуточного значения, оно получит неожиданные данные.

Решение: убрать дублирование. Если нужна цепочка вычислений — использовать смарт-скрипт.


2. Пакет на переходе vs пакет на таймере (расписании)

Контекст выполнения пакета зависит от того, откуда он вызван. Одинаковый пакет может работать на переходе и падать на расписании.

2.1 Контекст задачи

Контекст и данные, доступные пакету в зависимости от источника запуска:

Источник запуска Контекст задачи Параметры события Пользователь
Событие перехода (до/после) Текущая задача Переход, пользователь-инициатор Тот, кто инициировал переход
Событие ДП Текущая задача Старое/новое значение ДП Тот, кто изменил ДП
Расписание «Вне контекста задачи» Нет Нет Системный робот
Расписание «Для каждой задачи по фильтру» Текущая задача из итерации Нет параметров события Системный робот
Произвольное событие Зависит от вызова Параметры пользовательского события Зависит от вызова

Ключевое отличие: при выполнении из расписания нет параметров события. Если смарт-выражение в действии ссылается на параметр события (например, «Инициатор перехода»), оно вернёт null.

2.2 Ошибка: пакет работает на переходе, падает на расписании

Симптом: пакет привязан и к событию перехода, и к расписанию. На переходе работает, на расписании — ошибка или пустой результат.

Причина: действия в пакете используют параметры события (инициатор, переход, старое значение ДП), которых нет при запуске по расписанию.

Решение:

  1. Не переиспользовать один пакет для разных типов источников. Создать отдельный пакет для расписания.
  2. Если переиспользование необходимо — заменить ссылки на параметры события на смарт-выражения, которые вычисляют значение из контекста задачи (например, текущий исполнитель вместо «Инициатор перехода»).

Ошибка «пакет из расписания не видит задачи»:

Симптом: расписание срабатывает (видно в логе), но пакет не обрабатывает ни одной задачи.

Причины (проверять по порядку):

  1. Режим «Вне контекста задачи» — пакет не итерирует задачи. Нужен режим «Для каждой задачи по фильтру».
  2. Смарт-фильтр расписания содержит WHERE TaskID = @ContextID — остаток от конвертации смарт-выражения в TSQL. Убрать эту проверку.
  3. В категории нет ни одной задачи — расписание не запускается.

3. Привязка пакетов к расписаниям — потеря видимости

3.1 «Пакеты действий затерлись в Расписаниях»

Симптом: после обновления названия пакета расписание перестаёт показывать пакет в интерфейсе. Или: расписание ссылается на пакет, но в списке расписаний название пакета пустое.

Причина: расписание хранит ActionPackID (ссылка на ActionsPacks). Если пакет был удалён и пересоздан с тем же названием — ID изменился, старая привязка сломана. Имя пакета — отображаемое свойство, не ключ.

Решение:

  1. Не удалять и пересоздавать пакеты. Редактировать существующие.
  2. Если пакет уже удалён — открыть расписание на редактирование и выбрать новый пакет из списка.
  3. Диагностика: проверить ActionPackID в привязке и убедиться, что он существует в ActionsPacks.
-- Расписания с несуществующими пакетами
SELECT sr.ID, sr.SubcatID, sr.ActionsPackID, sr.Enabled
FROM SmartRecurrence sr
LEFT JOIN ActionsPacks ap ON sr.ActionsPackID = ap.ID
WHERE ap.ID IS NULL;

Название пакета с апострофами:

Симптом: пакет не открывается, не редактируется, интерфейс показывает ошибку.

Причина: апострофы (') в названии пакета ломают интерфейс. Кавычки (") допустимы.

Решение: убрать апострофы из названия. Через API:

PUT /api/admin/smart/packs/{packId}
Или напрямую в БД (только если интерфейс недоступен):
UPDATE ActionsPacks SET Name = REPLACE(Name, '''', '') WHERE ActionPackID = @id;


4. Тихие сбои — пакет «молча» не работает

4.1 Действие выполняется от имени пользователя без прав

Симптом: действие в логе отмечено как выполненное, но эффекта нет. Или: ошибка 403 в ExceptionsLog.

Причина: действие выполняется от имени пользователя, у которого нет прав на целевую категорию/задачу. Типичный случай: действие «Создать задачу» в другой категории от имени инициатора перехода, у которого нет доступа к целевой категории.

Решение: использовать системного робота (Диспетчер задач из Общих настроек приложения) как исполнителя действий, требующих широких прав.

Смарт-выражение возвращает неожиданный тип:

Симптом: действие пропускается без ошибки.

Причина: смарт-выражение в параметре действия возвращает тип, не совпадающий с ожидаемым. Например, строку вместо числа в поле «Задача», или пустой список вместо ID пользователя.

Решение: протестировать смарт-выражение отдельно через редактор выражений (кнопка «Тест»). Убедиться, что тип возвращаемого значения совпадает с типом параметра.

Пакет на событии «Перед...» отменяет событие:

Симптом: событие (переход, создание комментария, смена ДП) не происходит. Пользователь видит ошибку или ничего не видит.

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

Решение: проверить смарт-фильтр на событии. Действие «Отменить» должно быть обёрнуто в условие (смарт-фильтр на привязке к событию), которое ограничивает отмену конкретным сценарием.


5. Асинхронные пакеты — порядок не гарантирован

5.1 Два пакета на одном событии, один зависит от другого

Симптом: иногда пакет B видит изменения пакета A, иногда — нет.

Причина: флаг «Асинхронно» на привязке к событию. При включённой асинхронности пакеты выполняются параллельно, порядок не детерминирован.

Решение:

  1. Убрать флаг «Асинхронно», если пакеты зависят друг от друга.
  2. Объединить зависимые действия в один пакет — внутри пакета порядок всегда последовательный.

«Настройку [Асинхронно] следует включать только в том случае, если все пакеты действий в текущем событии не зависят друг от друга, т.е. порядок выполнения не важен, и одно действие не использует результат другого.»

5.2 Асинхронный пакет ушёл в очередь и «завис»

Симптом: действие не выполнилось. В журнале очередей запись со статусом Error или NotHandled.

Причина: ошибка в пакете при асинхронном выполнении уходит в MessageQueue. Если поток (MessageFlows) настроен с ActionOnError = Stop, одна ошибка блокирует весь поток.

Решение:

  1. Проверить MessageFlows — поле HasErrors и ActionOnError.
  2. Исправить причину ошибки в пакете.
  3. Перезапустить обработку потока (сбросить HasErrors).
-- Найти застрявшие события
-- QueueState: 0=NotHandled, 1=Success, 2=Error, 3=InProgress
SELECT TOP 50 Id, Created, State, ErrorDescr, ContextId, Flow
FROM MessageQueue
WHERE State IN (0, 2)  -- NotHandled или Error
ORDER BY Created DESC;

-- Проверить потоки с ошибками
SELECT Id, FlowName, HasErrors, FailedAttemptsCounter, ActionOnError
FROM MessageFlows
WHERE HasErrors = 1;

6. Отладка: как понять что пошло не так

6.1 Журнал автоматизации

Путь: Администрирование — Журналы — Автоматизация (лог Smart).

Журнал фиксирует выполнение смарт-пакетов и смарт-действий. Записи создаются только при включённом логировании: Общие настройки приложения — «Логировать выполнение smart запросов».

Что смотреть:

  • Тип = 4 (пакет) — факт запуска пакета, длительность
  • Тип = 2 (действие) — каждое действие внутри пакета
  • Тип = 9 (recurrence) — запуск расписания

Таблица БД: dbo.AutomationScriptsLog.

ExceptionsLog: исключения, возникшие при выполнении действий. Не отображаются в интерфейсе пользователю — только в журнале и в БД.

-- Ошибки автоматизации за последние сутки
SELECT TOP 100 ID, Date, Exception, SourceID, AppPool
FROM ExceptionsLog
WHERE Date > DATEADD(day, -1, GETDATE())
  AND Exception LIKE '%ActionPack%'
ORDER BY Date DESC;

Журнал очередей: для асинхронных пакетов. Таблицы: MessageQueue (текущие), MessageQueueLog (история). Путь в интерфейсе: Журналы — Очереди.

6.4 Алгоритм локализации проблемы

Как пошагово найти причину сбоя:

  1. Воспроизвести — выполнить действие, запускающее пакет.
  2. Лог автоматизации — есть ли запись о запуске пакета? Если нет — проблема в привязке (событие, фильтр, активность).
  3. Лог автоматизации — есть ли записи о каждом действии? Если нет — действие упало. Искать в ExceptionsLog.
  4. ExceptionsLog — текст исключения покажет причину (обращение к пустому значению, нехватка прав, невалидные параметры).
  5. Очереди — если пакет асинхронный, проверить MessageQueue на статус Error.

7. Чеклист перед запуском пакета

Что проверить перед сохранением пакета:

# Проверка Как проверить
1 Порядок действий логически корректен Каждое действие N+1 получает всё необходимое после N. Действия удаления — в конце.
2 Обязательные параметры заполнены В редакторе пакета все поля со * имеют значения. Смарт-выражения возвращают правильный тип.
3 Действия выполняются от имени пользователя с правами Если есть сомнения — системный робот.
4 Пакет не использует параметры события, которых нет Если пакет на расписании — нет параметров события. Если на «Перед/После ДП» — есть параметры ДП.
5 Асинхронные пакеты не зависят друг от друга Если два пакета на одном событии и один зависит от другого — убрать «Асинхронно».
6 Логирование включено Общие настройки — «Логировать выполнение smart запросов». Без этого диагностика невозможна.
7 Название пакета без апострофов Апострофы ломают интерфейс.